36

同じ長さの2つの配列がある場合-言う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

リストが短く、短い場合は、zipを使用しますa@Vincenzo Piiが示したように)。b

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

リストが長い場合は、itertools.izipを使用aメモリを節約します。b

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、デフォルトでイテレータを返すことに注意してください(つまりitertools.izip、Python2と同等です)。


関心のある他の変種:

于 2013-01-12T13:51:08.817 に答える
8

考えられる解決策はzip、あなたが言及したようにを使用することですが、質問での書き方とは少し異なります。

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

によって返されるタプルのリストの長さは、とzip()の長さの間の最小値に等しいことに注意してください。これは、とが同じ長さでない場合に影響します。abab

于 2013-01-12T13:44:43.857 に答える
7

特に速度が重要で、長い配列がある場合は、使用する代わりにNumpyzipを使用できます。はるかに高速で、numpy 配列を使用すると、ループは必要なく、次のように書くことができます。

print a + b

zip、izip、および numpy を使用してさまざまな長さのリストを合計する平均タイミングを示すグラフ: ここに画像の説明を入力

于 2013-01-12T14:57:35.623 に答える
1

別の回答で説明されているため、完全を期すためにこの回答を提供しnumpyます。上位の配列の値をペアにすることが役立つことがよくあります。

受け入れられた答えは、ランク1の任意のシーケンス/配列でうまく機能します。ただし、シーケンスが複数のレベル(numpyランク2以上の配列などlistlistまたはsまたはsの配列など)の場合tupletuple必要です各ランクを反復します。以下は、2Dnumpy配列の例です。

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)])

同じ概念は、同じ形状の 2 次元のネストされたシーケンスの任意のセットに対しても機能します。

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)]

ネストされたシーケンスの 1 つまたは両方に「穴」がある場合は、 を使用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 に答える