Python:如何迭代 3 个列表
Posted
技术标签:
【中文标题】Python:如何迭代 3 个列表【英文标题】:Python: How to iterate 3 lists 【发布时间】:2019-07-31 10:34:57 【问题描述】:在我自己的时间做一门名为 GeoPython 2018 的课程,并严重卡在第 3 课,练习 3 上。
目前的内容是条件语句、循环和列表(没有字典)。
问题:
我们被要求获取一个气象站名称列表、一个纬度列表和一个经度列表,并将它们划分为由临界值定义的 4 个区域(NE、NW、SE、SW)。
# Station names
stations = ['Hanko Russarö', 'Heinola Asemantaus', 'Helsinki Kaisaniemi',
'Helsinki Malmi airfield', 'Hyvinkää Hyvinkäänkylä', 'Joutsa Savenaho',
'Juuka Niemelä', 'Jyväskylä airport', 'Kaarina Yltöinen', 'Kauhava airfield',
'Kemi Kemi-Tornio airport', 'Kotka Rankki', 'Kouvola Anjala',
'Kouvola Utti airport', 'Kuopio Maaninka', 'Kuusamo airport',
'Lieksa Lampela', 'Mustasaari Valassaaret', 'Parainen Utö', 'Pori airport',
'Rovaniemi Apukka', 'Salo Kärkkä', 'Savonlinna Punkaharju Laukansaari',
'Seinäjoki Pelmaa', 'Siikajoki Ruukki', 'Siilinjärvi Kuopio airport',
'Tohmajärvi Kemie', 'Utsjoki Nuorgam', 'Vaala Pelso', 'Vaasa airport',
'Vesanto Sonkari', 'Vieremä Kaarakkala', 'Vihti Maasoja', 'Ylitornio Meltosjärvi']
# Latitude coordinates of Weather stations
lats = [59.77, 61.2, 60.18, 60.25, 60.6, 61.88, 63.23, 62.4,
60.39, 63.12, 65.78, 60.38, 60.7, 60.9, 63.14, 65.99,
63.32, 63.44, 59.78, 61.47, 66.58, 60.37, 61.8, 62.94,
64.68, 63.01, 62.24, 70.08, 64.5, 63.06, 62.92, 63.84,
60.42, 66.53]
# Longitude coordinates of Weather stations
lons = [22.95, 26.05, 24.94, 25.05, 24.8, 26.09, 29.23, 25.67,
22.55, 23.04, 24.58, 26.96, 26.81, 26.95, 27.31, 29.23,
30.05, 21.07, 21.37, 21.79, 26.01, 23.11, 29.32, 22.49,
25.09, 27.8, 30.35, 27.9, 26.42, 21.75, 26.42, 27.22,
24.4, 24.65]
# Cutoff values that correspond to the centroid of Finnish mainland
# North - South
north_south_cutoff = 64.5
# East-West
east_west_cutoff = 26.3
最终结果是使用正确分配的站名填充以下列表:
north_west = []
north_east = []
south_west = []
south_east = []
我已经在这可能 3-4 小时没有进展,尝试使用字典
data = ['station':stat, 'latitude': lat, 'longitude': lon
for stat, lat, lon in zip(stations, lats, lons)
]
但我没有进一步说明,另外我得到的印象是课程组织者希望人们专注于迭代和条件。
任何建议或推动方向都会有所帮助。这也是我的第一篇文章,如果有不清楚的地方请见谅。
【问题讨论】:
您已经找到了How to iterate through two lists in parallel? 问题,因此您所要做的就是根据与您的截止值相关的 lon、lat 对将名称放入 4 个桶中。你有没有想出如何分类一个站?然后将这些知识应用到所有个电台。 【参考方案1】:您关注的课程是quite generous with hints,其中包括instructions on what you should accomplish with this exercise:
为芬兰的地理区域创建四个列表(即
nort_west
、north_east
、south_west
、south_east
) 迭代值并确定站点所属的地理区域提示:您应该创建一个循环重复
打印出每个地理区域的台站名称N
-number 次。创建一个变量N
,它应该包含 我们这里有车站。 您应该使用条件语句来确定一个站的纬度坐标是北还是南 芬兰的中心点 (26.3, 64.5
) AND 如果是经度 位置是该中心点的西部或东部。 您应该将电台名称插入正确的地理区域列表(第 1 步)
您涵盖了第 1 点,并找到了一种更有效的方法来完成第 2.1 点(循环遍历 3 个列表)。要完成第 2.2 点,请查看我在开始时链接到的那些提示,特别是 嵌套 if 语句部分。如果这不能帮助你解决这个问题,你想re-reach the conditional statements chapter。
他们想要做的基本结构是这样的:
north_west = []
north_east = []
south_west = []
south_east = []
N = len(stations)
for i in range(N):
station = stations[i]
lat = lats[i]
lon = lons[i]
if <<test to see if lon is east of 26.3>>:
if <<test to see if lat is north of 64.5>>:
# add station to the north_east list
else: # south or at 64.5
# add station to the south_east list
else: # west or at 26.3
if <<test to see if lat is north of 64.5>>:
# add station to the north_west list
else: # south or at 64.5
# add station to the south_west list
然后打印四个列表中的每个列表中的名称。请注意,此处省略了实际条件供您填写。
有更有效和“聪明”的方法可以实现上述目标,您发现了一种方法是for i in range(N):
,而for station, lat, lon in zip(....):
可以替换3 个单独的分配。但是,我现在会坚持上述模式。我在下面提供了一种不同的方法,将其隐藏为扰流板,以免过多地分散您的注意力:
如果你想变得超级聪明,你可以从
(boolean, boolean)
元组到这 4 个列表以选择每个列表: 地区 = # 北?,东? (假,假):西南, (假,真):south_east, (对,错):north_west, (真,真):north_east, 对于 zip 中的车站、经度、纬度(车站、经度、纬度): 地区[lat > 64.5, lon > 26.3].append(station) 但这绝对超出了课程要求。 :-)
【讨论】:
谢谢 Martijn 我非常感谢您花时间回答这个问题!我想我对哪些代码会遍历所有 3 个列表的索引感到困惑,但是查看您的答案并浏览材料确实很清楚。再次干杯!【参考方案2】:这是其中之一(抱歉,如果西经是较低的经度,则将 > 切换为
north_west = [ a["station"] for a in data if a["latitude"] > north_south_cutoff and a["longitude"] > east_west_cutoff ]
【讨论】:
【参考方案3】:建议是使用 enumerate 内置函数从第一个列表中获取索引和值(站名)。然后使用索引获取另外两个值(纬度和经度)并检查这些值以确定它们属于哪个区域。然后将此名称添加到结果列表 station_list[quatrant].append(name)
解决办法如下:
# Cutoff values that correspond to the centroid of Finnish mainland
# North - South
north_south_cutoff = 64.5
# East-West
east_west_cutoff = 26.3
# Station names
stations = ['Hanko Russarö', 'Heinola Asemantaus', 'Helsinki Kaisaniemi',
'Helsinki Malmi airfield', 'Hyvinkää Hyvinkäänkylä', 'Joutsa Savenaho',
'Juuka Niemelä', 'Jyväskylä airport', 'Kaarina Yltöinen', 'Kauhava airfield',
'Kemi Kemi-Tornio airport', 'Kotka Rankki', 'Kouvola Anjala',
'Kouvola Utti airport', 'Kuopio Maaninka', 'Kuusamo airport',
'Lieksa Lampela', 'Mustasaari Valassaaret', 'Parainen Utö', 'Pori airport',
'Rovaniemi Apukka', 'Salo Kärkkä', 'Savonlinna Punkaharju Laukansaari',
'Seinäjoki Pelmaa', 'Siikajoki Ruukki', 'Siilinjärvi Kuopio airport',
'Tohmajärvi Kemie', 'Utsjoki Nuorgam', 'Vaala Pelso', 'Vaasa airport',
'Vesanto Sonkari', 'Vieremä Kaarakkala', 'Vihti Maasoja', 'Ylitornio Meltosjärvi']
# Latitude coordinates of Weather stations
lats = [59.77, 61.2, 60.18, 60.25, 60.6, 61.88, 63.23, 62.4,
60.39, 63.12, 65.78, 60.38, 60.7, 60.9, 63.14, 65.99,
63.32, 63.44, 59.78, 61.47, 66.58, 60.37, 61.8, 62.94,
64.68, 63.01, 62.24, 70.08, 64.5, 63.06, 62.92, 63.84,
60.42, 66.53]
# Longitude coordinates of Weather stations
lons = [22.95, 26.05, 24.94, 25.05, 24.8, 26.09, 29.23, 25.67,
22.55, 23.04, 24.58, 26.96, 26.81, 26.95, 27.31, 29.23,
30.05, 21.07, 21.37, 21.79, 26.01, 23.11, 29.32, 22.49,
25.09, 27.8, 30.35, 27.9, 26.42, 21.75, 26.42, 27.22,
24.4, 24.65]
region_name = ['North-West', 'North East', 'South West', 'South East']
NW = 0
NE = 1
SW = 2
SE = 3
def divide_station(stations, lats, lons):
station_list = [[] for _ in range(SE+1)]
for index, name in enumerate(stations):
if lats[index] > north_south_cutoff:
quatrant = NE if lons[index] > east_west_cutoff else NW
else:
quatrant = SE if lons[index] > east_west_cutoff else SW
station_list[quatrant].append(name)
return station_list
north_west, north_east, south_west, south_east = divide_station(stations, lats, lons)
station_list = [north_west, north_east, south_west, south_east]
for index, region in enumerate(station_list):
print('\nRegion:', region_name[index])
for number, name in enumerate(region):
print('%2d. %s' % (number+1, name))
输出:
Region: North-West
1. Kemi Kemi-Tornio airport
2. Rovaniemi Apukka
3. Siikajoki Ruukki
4. Ylitornio Meltosjärvi
Region: North East
1. Kuusamo airport
2. Utsjoki Nuorgam
Region: South West
1. Hanko Russarö
2. Heinola Asemantaus
3. Helsinki Kaisaniemi
4. Helsinki Malmi airfield
5. Hyvinkää Hyvinkäänkylä
6. Joutsa Savenaho
7. Jyväskylä airport
8. Kaarina Yltöinen
9. Kauhava airfield
10. Mustasaari Valassaaret
11. Parainen Utö
12. Pori airport
13. Salo Kärkkä
14. Seinäjoki Pelmaa
15. Vaasa airport
16. Vihti Maasoja
Region: South East
1. Juuka Niemelä
2. Kotka Rankki
3. Kouvola Anjala
4. Kouvola Utti airport
5. Kuopio Maaninka
6. Lieksa Lampela
7. Savonlinna Punkaharju Laukansaari
8. Siilinjärvi Kuopio airport
9. Tohmajärvi Kemie
10. Vaala Pelso
11. Vesanto Sonkari
12. Vieremä Kaarakkala
【讨论】:
【参考方案4】:您可以使用 while 循环遍历所有这些纬度和经度值,然后检查条件
NW (lat>NWcutoff&lon<EWcutoff)
NE (lat>NWcutoff&lon>EWcutoff)
SW (lat<NWcutoff&lon<EWcutoff)
SE (lat<NWcutoff&lon>EWcutoff)
然后将电台名称附加到相应的列表中。
所以完整、简单和干净的代码应该是这样的:
stations = ['Hanko Russarö', 'Heinola Asemantaus', 'Helsinki Kaisaniemi', 'Helsinki Malmi airfield', 'Hyvinkää Hyvinkäänkylä', 'Joutsa Savenaho', 'Juuka Niemelä', 'Jyväskylä airport', 'Kaarina Yltöinen', 'Kauhava airfield', 'Kemi Kemi-Tornio airport', 'Kotka Rankki', 'Kouvola Anjala', 'Kouvola Utti airport', 'Kuopio Maaninka', 'Kuusamo airport', 'Lieksa Lampela', 'Mustasaari Valassaaret', 'Parainen Utö', 'Pori airport', 'Rovaniemi Apukka', 'Salo Kärkkä', 'Savonlinna Punkaharju Laukansaari', 'Seinäjoki Pelmaa', 'Siikajoki Ruukki', 'Siilinjärvi Kuopio airport', 'Tohmajärvi Kemie', 'Utsjoki Nuorgam', 'Vaala Pelso', 'Vaasa airport', 'Vesanto Sonkari', 'Vieremä Kaarakkala', 'Vihti Maasoja', 'Ylitornio Meltosjärvi']
lats = [59.77, 61.2, 60.18, 60.25, 60.6, 61.88, 63.23, 62.4, 60.39, 63.12, 65.78, 60.38, 60.7, 60.9, 63.14, 65.99, 63.32, 63.44, 59.78, 61.47, 66.58, 60.37, 61.8, 62.94, 64.68, 63.01, 62.24, 70.08, 64.5, 63.06, 62.92, 63.84, 60.42, 66.53]
lons = [22.95, 26.05, 24.94, 25.05, 24.8, 26.09, 29.23, 25.67, 22.55, 23.04, 24.58, 26.96, 26.81, 26.95, 27.31, 29.23, 30.05, 21.07, 21.37, 21.79, 26.01, 23.11, 29.32, 22.49, 25.09, 27.8, 30.35, 27.9, 26.42, 21.75, 26.42, 27.22, 24.4, 24.65]
i=0
north_south_cutoff = 64.5
east_west_cutoff = 26.3
north_east=[]
north_west=[]
south_east=[]
south_west=[]
for i in range(0,len(stations)):
if lats[i]>north_south_cutoff and lons[i]>east_west_cutoff:
north_east.append(str(stations[i]))
elif lats[i]<north_south_cutoff and lons[i]>east_west_cutoff:
south_east.append(str(stations[i]))
elif lats[i]>north_south_cutoff and lons[i]<east_west_cutoff:
north_west.append(str(stations[i]))
elif lats[i]<north_south_cutoff and lons[i]<east_west_cutoff:
south_west.append(str(stations[i]))
print(north_east)
print(north_west)
print(south_east)
print(south_west)
这将在根据偏移量比较经度和纬度后将所有站点放入相应的列表中。
【讨论】:
Python has no++
increment operator,您发布的代码不起作用。像这样的循环的 Python 习惯用法是在 zip()
迭代器上使用带有 range()
对象的 for
循环,或者更好。以上是关于Python:如何迭代 3 个列表的主要内容,如果未能解决你的问题,请参考以下文章