2011-02-14 4 views

答えて

33

あなたが知っているなら、(たとえば、そのリストをその場で変更する関数に渡すために)構成されたアイテムの完全なリストが必要な場合は、または、あなたが渡している引数を強制的に特定のポイントで完全に評価されるようにする場合は、zip()にしてください。

+1

タプルを再利用し、izipを使用しない本当の理由がないので、最初のケースではizipを高速化する方がよいでしょうか? – user1815201

+1

@ user1815201: 'izip'は、' tuple'が次の反復が始まる前に解放された場合にのみ 'tuple'を再利用するので、何も得られません。つまり、どんな損失も簡単なので、 'izip'を排他的に使用しない理由はほとんどないことに同意します。' list'が必要な場合は 'list'で折り返します。 Pythonコードに 'future_builtins import zip'を追加することで、これを実際に「適切な」方法で実行できます。これによりPythonの移行に備えて' zip'が 'izip'になります。 – ShadowRanger

4

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

+0

これが起こるかもしれない例を教えてもらえますか? –

+3

本当にありません。だからこそ私はitertools.izip()を好む傾向がありますが、利益は純粋に統計的なものになります。 –

+2

1つのケースでは、リストが必要な場合は、結果の項目にインデックスでアクセスするか、または全長を検索する必要がある場合です。 'lst = zip(lst_a、lst_b)'は 'lst [1]'または 'len(lst)'を許可します。しかし、 'ilst = itertools.izip(lst_a、lst_n)'の場合、 'ilst [1]'や 'len(ilst)'に失敗するでしょう。 –

79

zipはすべてのリストを一度に計算し、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 

一つの重要な違いは、「izip」はリストではなく、(例えば、インデックス作成など)は、リスト固有の機能をサポートしていない「izipオブジェクト」を返し、「ZIP」は実際のリストを返すことです

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

これ以外にも、 'izip'はメモリやサイクルを節約するのに役立ちます。

など。次のコードは、数サイクル後に出ることができるので、組み合わせリストのすべての項目を計算する必要はありません:zipを使用して

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 

はサイクルに入る前にすべて(a, b)カップルを計算しているだろう。

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

しかし、小さなリストがある場合は、おそらくzipが高速です。

+4

ありがとうございます。しかし、これは主に 'izip'が' zip'よりも優れていると答えます。 –

+6

あなたは正しいです。私は良い意思で始め、理論的なものに落ちた。 – Don

3

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

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

は、効率的な逐次処理に関連するPythonの概念を見上げて:指摘する価値はまだ、まだあまりにも明白zip` `賛成の

"generators" & "yield" 
"iterators" 
"lazy loading" 
+0

きちんと説明した。 –

関連する問題