2

注: python3のコード例ですが、質問はpython2も表しています( などに置き換え.keys.viewkeys

dictオブジェクトは、(場合によっては) セット操作をサポートするビュー メソッドを提供します。

>>> {'a': 0, 'b': 1}.keys() & {'a'}
{'a'}
>>> {'a': 0, 'b': 1}.items() & {('a', 0)}
{('a', 0)}

ただし、値ビューは集合演算子をサポートしていません:

>>> {'a': 0, 'b': 1}.values() & {0}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for &: 'dict_values' and 'set'

dict 値はハッシュ不可能なオブジェクトになる可能性があることを理解しています。そのため、値のセットを作成することは常に可能であるとは限りませんが、同じことが にも当てはまりますdict.itemsここでは、セット操作は実行時にのみ失敗します。.itemsdictを入力しますが、 set 操作.valuesはすぐに失敗します。

ドキュメントでは、エントリは一般に一意ではないため、 Values ビューは set-like として扱われないと述べていますが、これは説得力のある理由ではないよう{0, 0, 1, 2}です。

この行動の矛盾の本当の理由は何ですか?

4

4 に答える 4

3

セットとして扱う場合、値ディクショナリ ビューを作成するのに非常にコストのかかるオブジェクトにすることになります。セットとして使用する前に、すべての値のハッシュを計算する必要があります。特に、すべての値がハッシュ可能かどうかを前もって知らない場合は特に、大きな辞書に対してこれを行いたくありません。

そのため、これは明示的な操作として残しておく方がはるかに適切です。値をセットとして扱いたい場合は、明示的にセットにします。

values = set(yourdict.values())

このdict.items()動作は、キーが少なくとも一意であることを前もって知っているという事実に起因するため、各 (キー、値) のペアも一意です。内部では、メンバーシップ テストをキー ディクショナリ ビューに委譲できます。

しかし、その上で集合演算 (交差、結合など) を使用するとすぐに、辞書ビューではなく、新しいsetオブジェクトが作成されます。そして、そのようなsetオブジェクトの場合、(キー、値) ペアの両方の要素はハッシュ可能でなければなりません。ジェネリックset型はキーについて同じ仮定を行うことができず、その制約を維持することもできません ({'a': 0}.items() & {('a', 1)}完全に合法ですが、重複キーにつながるため)。

于 2014-07-18T18:21:33.180 に答える
0

その理由は、dict_values型に実装されていないか、dict_valuesクラスが明示的に禁止しているためです。

通常、値は一意ではないアイテムのリストであるため、値をセットに変換することはお勧めできません。それが必要な場合は、手動で変換してください。データが失われる可能性があるため、一般的には悪い考えであるため、許可されていないと思います。

于 2014-07-10T13:47:09.513 に答える
0

aでは、値dictを繰り返すことはできませんが、値を繰り返すことはできます。keysvalues

>>> d = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0}
>>> d.keys()
[0, 1, 2, 3, 4]
>>> d.values()
[0, 0, 0, 0, 0]
>>> d.items()
[(0, 0), (1, 0), (2, 0), (3, 0), (4, 0)]

でキーを繰り返すことはできませんが、で値を繰り返すことはできるため、メソッドはcuacks やa のようなアヒルのようなkeys()ものを返します。そのため、クアックとアヒルはセットのように見えますが、クアックとアヒルは.setdictvalues()keysvalueslist

于 2014-07-10T13:43:42.807 に答える