36

如果我有两个长度相同的数组 - 说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

4 回答 4

43

如果列表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默认返回一个迭代器(即它相当于itertools.izip在 Python2 中)。


其他感兴趣的变体:

于 2013-01-12T13:51:08.817 回答
8

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

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

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

于 2013-01-12T13:44:43.857 回答
7

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

print a + b

图表显示了使用 zip、izip 和 numpy 对不同长度列表求和的平均时间: 在此处输入图像描述

于 2013-01-12T14:57:35.623 回答
1

提供这个答案是为了完整性,因为numpy已经在另一个答案中讨论过,并且将来自更高排名数组的值配对在一起通常很有用。

接受的答案适用于任何等级为 1 的序列/数组。但是,如果该序列具有多个级别(例如numpy等级为 2 或更多的数组,也例如在 a listof lists 或tupleof tuples 中),则需要遍历每个等级。下面是一个二维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)]
于 2017-07-13T13:34:55.087 回答