是否有更简单/更快捷的方法来确定两个字典是否不相交而不是计算它们的交集?
对于我找到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)
但是我认为这是低效的,因为它总是计算整个交叉点(没有短路退出)。
有更好的想法吗?
答案 0 :(得分:3)
您正在寻找类似的东西:
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)
两者都会短路。
答案 1 :(得分:3)
不要转换成一套; dict_keys
对象已支持isdisjoint
。
d1.keys().isdisjoint(d2)
答案 2 :(得分:2)
仅编辑显示方法和时间
由于OP询问了执行此操作的最快方法,因此我根据(我希望)在我的机器上的公平测试对所讨论的方法进行了排名。目的是找出字典的键是否不相交,并且dict_keys.isdisjoint()
方法似乎胜过其他集合或列表操作。
然而,正如其他答案中所提到的,这将根据相对字典的大小以及它们是否不相交而有很大差异。
这些测试仅适用于两个相等(小)大小的不相交词典。
最快: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
第二快: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
第三快:列出比较和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
第四快:对称差异(^
)与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