[英]python filtering list of dict by dict containing several key-value pairs as conditions
[英]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.