list
Joachim 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
ください。