检查两个字典是否不相交

时间:2017-07-05 14:44:20

标签: python dictionary set-intersection disjoint-sets

是否有更简单/更快捷的方法来确定两个字典是否不相交而不是计算它们的交集?

对于我找到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)

但是我认为这是低效的,因为它总是计算整个交叉点(没有短路退出)。

有更好的想法吗?

3 个答案:

答案 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