簡體   English   中英

只查找幾個 dicts 的公共鍵值對:dict 交集

[英]Find only common key-value pairs of several dicts: dict intersection

我在列表中有 0 個或多個dict

>>> dicts = [dict(a=3, b=89, d=2), dict(a=3, b=89, c=99), dict(a=3, b=42, c=33)]

我想創建一個新的字典,它只包含上述所有字典中的鍵,並且只有值都相同:

>>> dict_intersection(*dicts)
{"a": 3}

我覺得應該有一種優雅的方式來編寫dict_intersection ,但我自己只是想出了不優雅和/或低效的解決方案。

>>> dict(set.intersection(*(set(d.iteritems()) for d in dicts)))
{'a': 3}

注意:除了鍵之外,此解決方案還要求字典值是可散列的。

由於鍵/值對必須已經在第一個字典中,因此您可以迭代此字典的項目。

dict(pair for pair in dicts[0].items() 
     if all((pair in d.items() for d in dicts[1:])))

看起來沒有 interjay 的答案那么優雅,但可以不受哈希值的限制。

編輯:將all表達式更改為生成器表達式以提高速度

這個怎么樣?

def intersect_two_dicts (d1, d2):
    return { k:v for k,v in d1.iteritems() if ((k in d2)and(d1[k]==d2[k])) }

def intersect_dicts (list_of_dicts):
    return reduce(intersect_two_dicts, list_of_dicts)

# Tests
dicts = [dict(a=3, b=89, d=2), dict(a=3, b=89, c=99), dict(a=3, b=42, c=33)]
print (intersect_two_dicts(dicts[0], dicts[1]))
print (intersect_dicts(dicts))

編輯(1):我不確定其中哪個最快。 set.intersection解決方案當然是最優雅的(一個襯里!)但我有興趣看到一些基准測試。

編輯(2):獎勵 - 獲取任何兩個字典都具有(鍵:值)對的字典條目:

{k:count for k,count in
 collections.Counter(itertools.chain(*[d.iteritems() for d in dicts])).iteritems()
 if count > 1}
>>> dicts
[{'a': 3, 'b': 89, 'd': 2}, {'a': 3, 'c': 99, 'b': 89}, {'a': 3, 'c': 33, 'b': 42}]
>>> sets = (set(d.iteritems()) for d in dicts)
>>> dict_intersection = dict(set.intersection(*sets))
>>> dict_intersection
{'a': 3}

一種稍微麻煩一點的方法:獲取每個字典的鍵列表,對每個列表進行排序,然后像合並它們一樣繼續操作(為每個列表保留一個索引,推進具有最小值的那個)。 每當所有索引都指向同一個鍵時,檢查值是否相等; 無論哪種方式,推進所有指數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM