什么是同时循环两个数组的pythonic方法?

时间:2013-01-12 13:40:54

标签: python

如果我有两个长度相同的数组 - 说ab

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 这样做的方法吗?

4 个答案:

答案 0 :(得分:19)

如果列表ab很短,请使用zip(如@Vincenzo Pii所示):

for x, y in zip(a, b):
    print(x + y)

如果列表ab很长,请使用itertools.izip来节省内存:

import itertools as IT
for x, y in IT.izip(a, b):
    print(x + y)

zip创建一个元组列表。如果ab很大,这可能会很麻烦(以记忆为单位)。

itertools.izip返回一个迭代器。迭代器不会生成完整的元组列表;它只产生for循环请求的每个项目。因此它可以为你节省一些时间。

在Python2中,在短列表上调用zip(a,b)比使用itertools.izip(a,b)更快。但是在Python3中请注意zip默认返回一个迭代器(即它相当于Python2中的itertools.izip)。


其他感兴趣的变体:

答案 1 :(得分:7)

正如您自己提到的,可能的解决方案是使用zip,但与您在问题中的写法略有不同:

for x, y in zip(a, b):
    print x, y

请注意,zip()返回的元组列表的长度将等于ab的长度之间的最小长度。当ab的长度不同时,这会产生影响。

答案 2 :(得分:4)

您可以使用Numpy,而不是使用zip,尤其是在速度很重要并且您有长数组的情况下。它更快,一旦你使用numpy数组,你不需要循环,只需写:

print a + b

图表显示使用zip,izip和numpy对不同长度列表求和的平均时间: enter image description here

答案 3 :(得分:0)

提供完整性的答案,因为numpy已经在另一个答案中讨论过了,并且通常有用的是将排序较高的数组中的值组合在一起。

accepted answer适用于排名为1的任何序列/数组。但是,如果序列是多个级别(例如排名为2或更高的numpy数组,还可以是一个list listtuple 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)]