等価性のテストは、Python 辞書の場合は次のようにするとうまく機能します。
first = {"one":"un", "two":"deux", "three":"trois"}
second = {"one":"un", "two":"deux", "three":"trois"}
print(first == second) # Result: True
しかし、2 番目の辞書には無視したい追加のキーがいくつか含まれています。
first = {"one":"un", "two":"deux", "three":"trois"}
second = {"one":"un", "two":"deux", "three":"trois", "foo":"bar"}
最初の辞書がすべてのキーと値とともに 2 番目の辞書の一部であるかどうかをテストする簡単な方法はありますか?
編集1:
この質問は重複していると思われます辞書に特定のものが含まれているかどうかをテストする方法キー、しかし私はキーのテストに興味がありますそしてその価値観同じキーが含まれているだけでは、2 つの辞書は等しくなりません。
編集2:
さて、4 つの異なる方法を使用していくつかの答えを得て、それらすべてが機能することを証明しました。高速なプロセスが必要なため、実行時間をそれぞれテストしました。1000 項目の 3 つの同一の辞書を作成しました。キーと値は長さ 10 のランダムな文字列でした。 と はsecond
追加third
のキーと値のペアを取得し、 の最後の非追加キーはthird
新しい値を取得しました。したがって、first
は のサブセットですsecond
が、 のサブセットではありませんthird
。モジュールを 10000 回繰り返して使用するとtimeit
、次の結果が得られました。
Method Time [s]
first.viewitems() <=second.viewitems() 0.9
set(first.items()).issubset(second.items()) 7.3
len(set(first.items()) & set(second.items())) == len(first) 8.5
all(first[key] == second.get(key, sentinel) for key in first) 6.0
最後の方法が一番遅いだろうと予想しましたが、2 位でした。しかし、方法 1 は他の方法すべてより優れています。
ご回答ありがとうございます!
ベストアンサー1
あなたは辞書ビュー:
# Python 2
if first.viewitems() <= second.viewitems():
# true only if `first` is a subset of `second`
# Python 3
if first.items() <= second.items():
# true only if `first` is a subset of `second`
辞書ビューはPython 3の標準Python 2 では、標準メソッドの前に を付ける必要がありますview
。これらはセットのように動作し、<=
そのうちの 1 つが別のメソッドのサブセットである (または等しい) かどうかをテストします。
Python 3 のデモ:
>>> first = {"one":"un", "two":"deux", "three":"trois"}
>>> second = {"one":"un", "two":"deux", "three":"trois", "foo":"bar"}
>>> first.items() <= second.items()
True
>>> first['four'] = 'quatre'
>>> first.items() <= second.items()
False
これは、ハッシュ化できない値もキーによってキーと値のペアがすでに一意になっているためです。ドキュメントはこの点について少しわかりにくいですが、変更可能な値 (リストなど) でも次のように機能します。
>>> first_mutable = {'one': ['un', 'een', 'einz'], 'two': ['deux', 'twee', 'zwei']}
>>> second_mutable = {'one': ['un', 'een', 'einz'], 'two': ['deux', 'twee', 'zwei'], 'three': ['trois', 'drie', 'drei']}
>>> first_mutable.items() <= second_mutable.items()
True
>>> first_mutable['one'].append('ichi')
>>> first_mutable.items() <= second_mutable.items()
False
また、all()
関数ジェネレータ式を使用して、object()
欠損値を簡潔に検出するためのセンチネルとして使用します。
sentinel = object()
if all(first[key] == second.get(key, sentinel) for key in first):
# true only if `first` is a subset of `second`
しかし、これは辞書ビューを使用する場合ほど読みやすく表現力に富んでいません。