如果我有两个长度相同的数组 - 说a
和b
a = [4,6,2,6,7,3,6,7,2,5]
b = [6,4,6,3,2,7,8,5,3,5]
for i in range(len(a)):
print a[i] + b[i]
而不是像这样:
i=0
for number in a:
print number + b[i]
i += 1
因为我更喜欢与使用的方法保持一致。
我知道zip
,但我从不使用它。这是为zip
制作的吗?
会
for pair in zip(a,b):
print pair[0] + pair[1]
是 pythonic 这样做的方法吗?
答案 0 :(得分:19)
如果列表a
和b
很短,请使用zip(如@Vincenzo Pii所示):
for x, y in zip(a, b):
print(x + y)
如果列表a
和b
很长,请使用itertools.izip来节省内存:
import itertools as IT
for x, y in IT.izip(a, b):
print(x + y)
zip
创建一个元组列表。如果a
和b
很大,这可能会很麻烦(以记忆为单位)。
itertools.izip
返回一个迭代器。迭代器不会生成完整的元组列表;它只产生for循环请求的每个项目。因此它可以为你节省一些时间。
在Python2中,在短列表上调用zip(a,b)
比使用itertools.izip(a,b)
更快。但是在Python3中请注意zip
默认返回一个迭代器(即它相当于Python2中的itertools.izip
)。
其他感兴趣的变体:
zip
。a
和b
长度不等。答案 1 :(得分:7)
正如您自己提到的,可能的解决方案是使用zip
,但与您在问题中的写法略有不同:
for x, y in zip(a, b):
print x, y
请注意,zip()
返回的元组列表的长度将等于a
和b
的长度之间的最小长度。当a
和b
的长度不同时,这会产生影响。
答案 2 :(得分:4)
您可以使用Numpy,而不是使用zip
,尤其是在速度很重要并且您有长数组的情况下。它更快,一旦你使用numpy数组,你不需要循环,只需写:
print a + b
图表显示使用zip,izip和numpy对不同长度列表求和的平均时间:
答案 3 :(得分:0)
提供完整性的答案,因为numpy
已经在另一个答案中讨论过了,并且通常有用的是将排序较高的数组中的值组合在一起。
accepted answer适用于排名为1的任何序列/数组。但是,如果序列是多个级别(例如排名为2或更高的numpy
数组,还可以是一个list
list
或tuple
tuple
个,需要遍历每个等级。以下是2D numpy
数组的示例:
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
b = np.array([list('abc'), list('pdq'), list('xyz')])
c = np.array([[frobnicate(aval, bval) for aval, bval in zip(arow, brow)] for arow, brow in zip(a, b)])
同样的概念适用于任何一组相同形状的二维嵌套序列:
a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
b = [list('abc'), list('pdq'), list('xyz')]
c = [[frobnicate(aval, bval) for aval, bval in zip(arow, brow)] for arow, brow in zip(a, b)]
如果其中一个或两个嵌套序列中有“洞”,请使用itertools.zip_longest
填充孔(填充值默认为None
但可以指定):
from itertools import zip_longest as zipl
a = [[], [4, 5, 6], [7, 8, 9]] # empty list in the first row
b = [list('abc'), list('pdq'), []] # empty list in the last row
c = [[frobnicate(aval, bval) for aval, bval in zipl(arow, brow)] for arow, brow in zipl(a, b)]