2017-07-05 4 views
1

2つの辞書が交差点を計算するよりも簡単で簡単な方法がありますか?交差点の場合2つの辞書が互いに素であるかどうかを確認する

は私がthis answerを見つけたので、ばらばらのテストは次のようになります。

def dicts_disjoint(a, b): 
    keys_a = set(a.keys()) 
    keys_b = set(b.keys()) 
    intersection = keys_a & keys_b 
    return not len(intersection) 

私はそれは常に(ない短絡が終了していない)全体の交差点を計算するので、これは非効率的だと思いますが。

もっと良いアイデアを教えてください。

def dicts_disjoint(a, b): 
    return not any(k in b for k in a) 

または::

def dicts_disjoint(a, b): 
    return all(k not in b for k in a) 

両短絡意志

答えて

3

次のようなものを探しています。方法とタイミングを表示する

+0

「すべて(kはaのkではbではない)」と読みやすいかもしれません。私はいつも 'not any'sを2度読む必要があります。xD –

+0

非常に真実です。 – AChampion

+0

これは設定された交差点よりも**高速**(OPが欲しい)ですか? – randomir

2

編集のみ

OPは、この操作を実行するための最速の方法について尋ねられたので、私は私のマシン上で(私は願っています)公正な試験により検討中のものをランク付けしました。目的は、辞書のキーがばらばらになっているかどうかを調べることで、dict_keys.isdisjoint()メソッドが他のセットまたはリスト操作よりも勝つようです。

しかし、他の回答に記載されているように、これは相対辞書のサイズおよびそれらが互いに素であるかどうかによって大きく異なります。

これらのテストは、等しい(小さい)サイズの2つの分離した辞書に対してのみ行われます。

最速:dict_keys.isdisjoint()

例:

{"a": 1, "b": 2, "c": 3 }.keys().isdisjoint({ "d": 4, "e": 5, "f": 6}.keys()) 

タイミング:

>>> timeit.timeit('{"a": 1, "b": 2, "c": 3 }.keys().isdisjoint({ "d": 4, "e": 5, "f": 6}.keys())') 
0.4637166199972853 

2番手:set.isdisjoint()

例:

set({"a": 1, "b": 2, "c": 3 }.keys()).isdisjoint(set({ "d": 4, "e": 5, "f": 6}.keys())) 

タイミング:

>>> timeit.timeit('set({"a": 1, "b": 2, "c": 3 }.keys()).isdisjoint(set({ "d": 4, "e": 5, "f": 6}.keys()))') 
0.774243315012427 

3番手:リストコンプとall()

例:

all(k not in {"a": 1, "b": 2, "c": 3 } for k in { "d": 4, "e": 5, "f": 6}) 

タイミング:

>>> timeit.timeit('all(k not in {"a": 1, "b": 2, "c": 3 } for k in { "d": 4, "e": 5, "f": 6})') 
0.8577601349970791 

4番手:not()

と対称差(^)例:

not set({"a": 1, "b": 2, "c": 3 }.keys())^set({ "d": 4, "e": 5, "f": 6}.keys()) 

タイミング:

>>> timeit.timeit('not set({"a": 1, "b": 2, "c": 3 }.keys())^set({ "d": 4, "e": 5, "f": 6}.keys())') 
0.9617313010094222 
+0

これはもちろん、鍵が共有されていないかどうかを調べるだけの場合です。 –

+1

'not bool(x)'は 'not x'です。 'set 'で変換するのは時間の無駄であり、短絡することはありません。 '^'は短絡しません。 – Veedrac

+0

良い点@Veedrac - 読みやすさを助けるために 'bool()'と書くこともありますが、それを取り除くことでスクリプトが大幅にスピードアップします。あなたは '^'を短絡することについて何を意味するのかよく分かりません。この操作は、自分の知識に基づいたセットでのみ機能します... –

3

セットに変換しません。 dict_keysオブジェクトはすでにisdisjointをサポートしています。

d1.keys().isdisjoint(d2) 
+0

+1、Python 3のみですが、これは分かりませんでした。 '.keys()'によって提供される唯一の(非プライベート)メソッドです。 –

関連する問題