1

免責事項として、私はプログラミングに比較的慣れていないので、この質問を書く際に私が行った単純な見落としを許してください。

私はPython2.7.3を使用していますが、その際に、私には珍しいと思われることに気づき、Google検索またはPythonドキュメントで満足のいく説明を見つけることができませんでした。リストを作成し、zip()を使用して次のようなタプルのリストを作成できます。

numList = range(4)
print zip(numList, numList)

[(0, 0), (1, 1), (2, 2), (3, 3)]

しかし、numListでiter()関数を使用して反復可能なオブジェクトを作成し、このオブジェクトで同様の方法でzip()を使用すると、結果が大きく異なります。

numList = range(4)
numList = iter(numList)
print zip(numList, numList)

[(0, 1), (2, 3)]

誰かが2つの手順の違いと、これを引き起こす舞台裏で何が起こっているのかを説明していただければ幸いです。

4

2 に答える 2

6

最初のケースではzip、「2つの」リスト(実際には同じオブジェクト、つまりリストですが、2つの参照を提供します)を提供するため、各リストから同じ情報を交互に引き出し、「zip」します。情報を使用しても消費されません。

2番目のケースでは、0から3までの値を「オンザフライ」/オンデマンドで生成するイテレーターを作成します。

ここで、このイテレーターをzipに2回提供します(これもイテレーターへの同じ参照です)。これにより、各イテレーターから交互にデータが「プルアウト」されます。(つまり、イテレータのnext()関数を呼び出します)。

「最初の」イテレータは最初の値を提供し0、「2番目の」イテレータ(実際には同じ値への参照)は次の値1を提供し、以下同様にイテレータがで使い果たされるまで交互に実行され3ます。

したがって、覚えておくべき主なことはzip、両方の場合に提供したのは、同じオブジェクトへの2つの同一の参照であるということです。最初のケースでは、リストにはすでにインターリーブ/圧縮されているすべてのデータが含まれています(データにアクセス/使用してもデータは使用できなくなりません)。2番目のケースでは、データはオンデマンドで生成されているため、生成されたシーケンスはインターリーブ/圧縮され、各値が生成されるたびに消費され、その後は使用できなくなります。

これが理にかなっていることを願っています(一枚の紙にスケッチする方が簡単です:)

于 2012-08-22T21:28:13.317 に答える
3

イテレータを反復処理すると、要素がイテレータから消費されるため、各数値は1回だけ発生します。

同じリストを2回繰り返すと、2つの別々のリストイテレータが作成され、それぞれが1回番号を生成するため、全体として各番号は2回発生します。

あなたの最初のプログラムはすることと同等です

print zip(iter(numList), iter(numList))
于 2012-08-22T21:27:11.393 に答える