有没有更好的方法迭代两个列表,每次迭代从每个列表中获取一个元素?

162
我有一个纬度列表和一个经度列表,需要遍历每个纬度和经度组成的一对。
以下哪种方法更好:
A. 假设这两个列表长度相等:
for i in range(len(Latitudes)):
    Lat,Long=(Latitudes[i],Longitudes[i])
for Lat,Long in [(x,y) for x in Latitudes for y in Longitudes]:

(请注意,B是不正确的。这会给我所有的配对,相当于itertools.product()

对于每个方法,你有什么想法或者哪个更符合Python风格?

7个回答

307

这是你可以达到的最Pythonic的写法:

for lat, long in zip(Latitudes, Longitudes):
    print(lat, long)

25
在Python 2.x中,你可能需要考虑使用itertools.izip(在Python 3.x中可以使用zip完成相同的操作)。 - Nicholas Riley
2
@NicholasRiley:介意说一下原因吗? - User
5
它使用更少的内存,可能更快; 它创建了一个迭代器而不是一个中间列表。 - Nicholas Riley
如果我还想要索引 i ,怎么办? 我能在 zip 函数里用 enumerate 包裹一下吗? - Charlie Parker
@CharlieParker 是的,你可以。 - Roberto Bonvallet
1
对于索引,使用enumerate(zip(Latitudes, Longitudes))来遍历(lat,long)。 - Sean Anderson

53

另一种做法是使用map函数。

>>> a
[1, 2, 3]
>>> b
[4, 5, 6]
>>> for i,j in map(None,a,b):
    ...   print i,j
    ...
1 4
2 5
3 6

使用map与zip的一个区别是,使用zip时新列表的长度与最短列表的长度相同。
例如:

>>> a
[1, 2, 3, 9]
>>> b
[4, 5, 6]
>>> for i,j in zip(a,b):
    ...   print i,j
    ...
1 4
2 5
3 6

在同一数据上使用 map:

>>> for i,j in map(None,a,b):
    ...   print i,j
    ...

    1 4
    2 5
    3 6
    9 None

能不能像这样做:14、15、16? - BomberMan
1
地图解决方案在Python 3.6中无法正常工作。我不得不使用itertools.zip_longest(a,b)来达到相同的效果。 - J_Scholz

22

很高兴在这里看到许多人喜欢使用zip

然而需要注意的是,如果你正在使用Python 3.0之前的版本,则标准库中的itertools模块包含一个izip函数,它返回一个可迭代对象,在这种情况下更为合适(特别是如果你的latt/longs列表非常长)。

在Python 3及更高版本中,zip的行为类似于izip


15

假设你的纬度和经度列表很大且是懒加载的:

from itertools import izip
for lat, lon in izip(latitudes, longitudes):
    process(lat, lon)

或者如果你想避免使用for循环

from itertools import izip, imap
out = imap(process, izip(latitudes, longitudes))

7

同时迭代两个列表中的元素被称为“压缩”,Python提供了一个内置函数,用于此操作,具体文档在这里

>>> x = [1, 2, 3]
>>> y = [4, 5, 6]
>>> zipped = zip(x, y)
>>> zipped
[(1, 4), (2, 5), (3, 6)]
>>> x2, y2 = zip(*zipped)
>>> x == list(x2) and y == list(y2)
True

在您的情况下,它将会是简单的:
for (lat, lon) in zip(latitudes, longitudes):
    ... process lat and lon

6
for Lat,Long in zip(Latitudes, Longitudes):

5
这篇文章帮助我理解了zip()函数。虽然我来晚了几年,但我仍想做出贡献。这是Python 3的内容。
注意:在Python 2.x中,zip()返回一个元组列表;在Python 3.x中,zip()返回一个迭代器。itertools.izip()在Python 2.x中等同于Python 3.x中的zip()
由于看起来你正在构建一个元组列表,以下代码是实现你所需功能的最Pythonic的方式。
>>> lat = [1, 2, 3]
>>> long = [4, 5, 6]
>>> tuple_list = list(zip(lat, long))
>>> tuple_list
[(1, 4), (2, 5), (3, 6)]

或者,你也可以使用列表解析(或简称为 list comps)进行更复杂的操作。列表解析的执行速度与 map() 函数相当,并且已成为被认为是 Pythonic 的新规范,而不是使用 map()

>>> lat = [1, 2, 3]
>>> long = [4, 5, 6]
>>> tuple_list = [(x,y) for x,y in zip(lat, long)]
>>> tuple_list
[(1, 4), (2, 5), (3, 6)]
>>> added_tuples = [x+y for x,y in zip(lat, long)]
>>> added_tuples
[5, 7, 9]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接