13

dict メソッド dict.keys()、dict.items() および dict.values() は、リストの代わりに「ビュー」を返します。 http://docs.python.org/dev/3.0/whatsnew//3.0.html

まず、ビューとイテレータの違いは何ですか? 第二に、この変更の利点は何ですか? パフォーマンス上の理由だけですか?

私には直感的ではないように思えます。つまり、物のリストを求めているのに (すべてのキーを渡してください)、別のものが返ってきます。これは人々を混乱させるでしょうか?

4

3 に答える 3

15

効果的にリストを取得しています。これは内部リストのコピーではなく、リストのように機能するが、内部状態のみを表すものです。

これは、Java で実装されているのと同じ方法です (おそらく他の多くの言語/環境でも同様です)。

主な理由は、多くのユースケースで、完全に切り離されたリストを返すことは不要で無駄が多いためです。コンテンツ全体をコピーする必要があります (多くない場合もあります)。

キーを反復処理するだけの場合は、新しいリストを作成する必要はありません。実際に別のリストとして (コピーとして) 必要な場合は、ビューからそのリストを簡単に作成できます。

于 2008-12-04T14:59:04.603 に答える
6

listJoachim Sauer's answer は、 aが返されない理由をよく説明しています。しかし、これはなぜこれらの関数がイテレータを返さないのかという疑問を残しますiteritems.

イテレーターは、コンテナーよりもはるかに制限的です。たとえば、反復子は複数のパスを許可しません。2 番目のパスを試すと、空であることがわかります。したがって、 のような操作elem in contはコンテナでサポートされていますが、イテレータではサポートできません。要素がイテレータの「内」にあるかどうかを確認すると、イテレータは破棄されます!

一方、コンテナーを取得するには、通常、辞書のキーからリストを作成するなど、コピーを作成する必要があります。

オブジェクトは両方のview長所を備えています: コンテナとして動作しますが、ディクショナリのコピーは作成しません! 実際、これは、基礎となるディクショナリにリンクすることによって機能する一種の仮想読み取り専用コンテナーです。標準の Python の他の場所で見られるかどうかはわかりません。

編集:

@AntonyHatchkins: ジェネレーター関数を返さない理由は、高速なin操作ができないためです。はい、inジェネレーター関数で機能します (呼び出すとき)。つまり、次のことができます。

def f():
  for i in range(10):
    yield i

5 in f() # True

しかし、 の定義によるとin、右側がジェネレーターの場合、python はジェネレーターのすべてのn項目を処理するため、O(n)時間の複雑さが生じます。それが任意のジェネレーターの唯一の意味のある動作であるため、それについてできることは何もありません。

一方、ディクショナリ ビューの場合は、自分inが管理するデータについて詳しく知っているので、好きなように実装できます。実際には、ハッシュ テーブルを使用して複雑inに実装されています。O(1)実行することで確認できます

>>> d = dict(zip(range(50000000), range(50000000)))
>>> 49999999 in d
True
>>> 49999999 in iter(d) # kinda how generator function would work
True
>>>

inそして、最初のものが 2 番目に比べてどれだけ速いかに注目してinください。

于 2012-01-26T18:53:12.993 に答える
0

関連する質問ですでに述べたように、ビューにはlen()メソッドがあり、イテレータにはありません(まだリストにはあります)。

リストの代わりにビューを返すもう 1 つの利点は、少なくともキーについては、リスト (または反復子) の O(N) ではなく、O(1) 操作で最適化されたメンバーシップ テストがあることです。

于 2014-10-24T17:44:11.490 に答える