3

Python 2.x でリストを返すために使用されていた多くのメソッドは、Py3k ではイテレータを返すようになりました

イテレータもジェネレータ式ですか? 遅延評価?

したがって、これにより、Python のメモリ フットプリントが大幅に削減されます。ではない?

組み込みスクリプトを使用して 2to3 から変換されたプログラムについてはどうでしょうか。

組み込みツールは、互換性のために、返されたすべての反復子をリストに明示的に変換しますか? その場合、Py3k のメモリ フットプリントが小さいという利点は、変換されたプログラムでは実際には明らかではありません。それは...ですか?

4

3 に答える 3

7

それらの多くはイテレータではなく、特別なビュー オブジェクトです。たとえば、range() は古い xrange オブジェクトに似たものを返すようになりました。これは引き続きインデックスを作成できますが、必要に応じて整数を遅延構築します。

同様に、 dict.keys() は、キーのコピーで新しいリストを作成するのではなく、辞書のビューを実装する dict_keys オブジェクトを提供します。

これがメモリフットプリントにどのように影響するかは、おそらくプログラムによって異なります。確かに、リストが本当に必要でない限り、イテレータの使用に重点が置かれていますが、リストの使用は一般的に python2 のデフォルトのケースでした。これにより、平均的なプログラムのメモリ効率が向上する可能性があります。ただし、非常に大きなメモリ使用量が目立ち、すでに対処されている可能性が高いため、非常に大きな節約がある場合は、python2 プログラムのイテレータとして既に実装されている可能性があります。file.readlines()(例: ファイル反復子は、以前の方法よりもはるかにメモリ効率が高い)

変換は 2to3 ツールによって行われ、通常は range() のようなものを、実際のリストが不要であると安全に判断できる反復子に変換します。そのため、次のようなコードを作成します。

for x in range(10): print x

新しい range() オブジェクトに切り替わり、リストを作成しなくなるため、メモリの利点が減少しますが、コードは次のようになります。

x = range(20)

次のように変換されます。

x = list(range(20))

コンバーターは、コードが x に実際のリスト オブジェクトを期待しているかどうかを判断できないためです。

于 2009-03-31T16:27:59.560 に答える
1

イテレータはジェネレータ式でもありますか?遅延評価?

イテレータは、nextメソッドを持つ単なるオブジェクトです。関数がイテレータを返すと言っているときにドキュメントが意味することは、その結果が遅延ロードされるということです。

したがって、これにより、Pythonのメモリフットプリントは大幅に削減されます。ではない?

場合によります。しかし、平均的なプログラムは大きな違いに気付かないと思います。リストに対するイテレータのパフォーマンス上の利点は、データセットが大きい場合にのみ重要です。この質問を見たいと思うかもしれません。

于 2009-03-31T16:39:11.030 に答える
0

リストに対する反復子の最大の利点の 1 つはメモリではなく、実際には計算時間です。たとえば、Python 2 では次のようになります。

for i in range(1000000):  # spend a bunch of time making a big list
    if i == 0:
        break  # Building the list was a waste since we only looped once

たとえば、次のようにします。

for i in xrange(1000000):  # starts loop almost immediately
    if i == 0:
        break  # we did't waste time even if we break early

例は不自然ですが、ユースケースはそうではありません: ループはしばしば途中で中断されます。リスト全体を作成してその一部のみを使用するのは、複数回使用しない限り無駄です。その場合は、リストを明示的に作成できます: r = list(range(100)). これが、Python 3 のより多くの場所で反復子がデフォルトになっている理由です。必要なときにリスト (または他のコンテナー) を明示的に作成できるため、何も問題はありません。しかし、イテラブルを 1 回反復処理するだけでよい場合は、その必要はありません (これはもっと一般的なケースだと思います)。

于 2015-02-20T23:21:10.167 に答える