根据任意字段查找字典列表的交集

时间:2018-08-30 19:42:25

标签: python list dictionary intersection

说我有一个字典l1l2的列表。每个字典都包含相同格式的字典。我想根据字典的某个字段找到l1l2的交集。

例如,让

l1 = [{"key":1, "key2":2}, {"key":1, "key2":0}],
l2 = [{"key":0, "key2":2}]. 

我想根据“ key2”将它们相交。 因此,l1.intersect(l2) = 2

我可以按以下步骤进行操作,如果我没记错的话,它的复杂度为O(len(l1)+ len(l2))。

d = defaultdict(bool)
for e in l2:
    d[e['key2']] = True
intersection=set()
for e in l1:
    if d[e['key2']]:
        intersection.add(e['key2])

我想知道是否存在更好的解决方案,或者我的解决方案是否已经达到最佳状态。

1 个答案:

答案 0 :(得分:4)

您可以使用set comprehensions使它紧凑。例如,

l1 = [{"key":1, "key2":2}, {"key":3, "key2":4}, {"key":5, "key2":6}, {"key":7, "key2":8}]
l2 = [{"key":0, "key2":2}, {"key":1, "key2":3}, {"key":2, "key2":4}]

key = "key2"
values = {d[key] for d in l1} & {d[key] for d in l2}
print(values)

输出

{2, 4}

您可以通过对函数进行设置理解来使代码更具可读性,尽管函数调用会使代码的运行变慢。

def key_set(seq, key):
    return {d[key] for d in seq}

values = key_set(l1, key) & key_set(l2, key)

该技术可以推广到处理任意数量的列表。

all_lists = (l1, l2)
key = "key2"
values = set.intersection(*({d[key] for d in seq} for seq in all_lists))