質問

  

dictメソッドdict.keys()、dict.items()   およびdict.values()return <!>#8220; views <!>#8221;   リストの代わりに。    http://docs.python.org/dev/3.0/whatsnew//3.0 .html

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

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

役に立ちましたか?

解決

実質的にリストを取得しています。これは単に内部リストのコピーではなく、リストがあるが内部状態のみを表すかのように動作するものです。

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

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

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

他のヒント

Joachim Sauerの答えは、listが返されない理由を非常によく説明しています。しかし、Python 2でiteritemsなどが行ったように、これらの関数がイテレーターを返さない理由は疑問です。

イテレータは、コンテナよりもはるかに制限的です。たとえば、イテレータは複数のパスを許可しません。 2回目のパスを試すと、空であることがわかります。したがって、コンテナではelem in contなどの操作がサポートされていますが、イテレータではサポートできません。要素が<!> quot; in <!> quot;イテレーター、イテレーターは破壊されます!

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

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

編集:

@AntonyHatchkins:ジェネレーター関数を返さない理由は、高速のin操作を許可しないためです。はい、nはジェネレータ関数に対して機能します(それらを呼び出すとき)。つまり、これを行うことができます:

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

5 in f() # True

ただし、O(n)の定義によれば、右側がジェネレーターである場合、PythonはジェネレーターのすべてのO(1)アイテムを通過します。これにより、<=>時間の複雑さが生じます。それが任意のジェネレーターにとって唯一の意味のある動作であるため、あなたはそれについて何もすることができません。

一方、ディクショナリビューの場合は、管理するデータの詳細を知っているため、<=>を任意の方法で実装できます。実際、ハッシュテーブルを使用して<=>が<=>複雑さで実装されています。実行して確認できます

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

および最初の<=>が2番目の<=>と比較される速度に注目します。

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top