izipの代わりにzipを使用する方が良いのはいつですか?


82

zip代わりに使用する方が良いのはitertools.izipいつですか?


zipあまりにも明白であるがまだ指摘する価値があることを支持する1つの理由は、一度だけトラバースできるをizip返すiteratorことです。つまり、ii = izip(a,b) ; f(ii) ; g(ii)では、ここでは空のリスト[]がに渡されgます。
因果関係2016

6
参考までに、Python3のzip関数はPython2の関数ですizip。一般に、Python 3は、範囲、フィルター、dict関数などのイテレーターを使用するようにほとんどの関数を変更しました
Charles L.

回答:


44

アイテムの完全なリストを作成する必要があることがわかっている場合(たとえば、そのリストをインプレースで変更する関数に渡すため)。または、渡す引数をzip()その特定のポイントで完全に評価するように強制したい場合。


1
最初のケースでは、タプルを再利用し、izipを使用しない本当の理由がないため、izipを使用する方が速いのではないでしょうか。
user1815201 2013年

1
@ user1815201:次の反復が始まる前にがリリースされiziptuple場合にのみ再利用するtupleため、何も得られません。とは言うものの、損失も些細なことなので、必要に応じてizipラッピングしてlist、排他的に使用しない理由はほとんどないことに同意しますlist。実際には、from future_builtins import zipPy2コードに追加することで、これを「適切な」方法で行うことができます。これによりzipizip(Py3遷移の準備)がわかりやすくなります。
ShadowRanger 2015

99

zipすべてのリストを一度にizip計算し、要求された場合にのみ要素を計算します。

重要な違いの1つは、「zip」が実際のリストを返し、「izip」が「izipオブジェクト」を返すことです。これはリストではなく、リスト固有の機能(インデックス作成など)をサポートしていません。

>>> l1 = [1, 2, 3, 4, 5, 6]
>>> l2 = [2, 3, 4, 5, 6, 7]
>>> z = zip(l1, l2)
>>> iz = izip(l1, l2)
>>> isinstance(zip(l1, l2), list)
True
>>> isinstance(izip(l1, l2), list)
False
>>> z[::2] #Get odd places
[(1, 2), (3, 4), (5, 6)]
>>> iz[::2] #Same with izip
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'itertools.izip' object is unsubscriptable

したがって、リスト(リストのようなオブジェクトではない)が必要な場合は、「zip」を使用してください。

これとは別に、「izip」はメモリやサイクルを節約するのに役立ちます。

たとえば、次のコードは数サイクル後に終了する可能性があるため、結合リストのすべての項目を計算する必要はありません。

lst_a = ... #list with very large number of items
lst_b = ... #list with very large number of items
#At each cycle, the next couple is provided
for a, b in izip(lst_a, lst_b):
    if a == b:
        break
print a

を使用zipすると、サイクルに入る前にすべての (a, b)カップルが計算されます。

さらに、lst_alst_bが非常に大きい場合(たとえば、数百万のレコード)、zip(a, b)2倍のスペースを持つ3番目のリストを作成します。

ただし、リストが小さい場合は、おそらくzip高速です。


9
あなたが正しい。私は善意から始めて、それから理論的なものに陥りました...
ドン

6

itertoolsライブラリは、一般的なPython関数の「イテレータ」を提供します。itertoolsのドキュメントから、「リストの代わりにイテレータを返すことを除いて、zip()と同様です。」izip()のIは「イテレータ」を意味します。

Pythonイテレータは、通常のメモリ内リストよりもメモリを節約する「遅延読み込み」シーケンスです。したがって、2つの入力a、bが大きすぎて一度にメモリに保持できない場合は、itertools.izip(a、b)を使用します。

効率的な順次処理に関連するPythonの概念を調べます。

"generators" & "yield"
"iterators"
"lazy loading"

うまく説明されました。
Rahul 2017年

5

2.xでは、イテレータの代わりにリストが必要な場合。


それが起こる可能性のある例を教えてください。
ニールG

3
あんまり。itertools.izip()ゲインが純粋に統計的である場合を除いて、私が好む傾向があるのはそのためです。
Ignacio Vazquez-Abrams

2
リストが必要な場合の1つのケースは、インデックスによって結果のアイテムにアクセスすることを計画している場合、または全長を見つける必要がある場合です。lst = zip(lst_a, lst_b)許可lst[1]またはlen(lst)。ただし、またはをilst = itertools.izip(lst_a, lst_n)実行しようとすると失敗します。ilst[1]len(ilst)
Jan Vlcinsky 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.