如何从嵌套字典中查找公共键值对

How to find common key value pairs from within nested dictionaries

我有这个嵌套字典:

Movies = {1: {'1060277': 'cloverfield', '1877830': 'The Batman', '0117283': 'The Pallbearer'},
          2: {'1877830': 'The Batman', '1877321': 'The Yards', '0117283': 'The Pallbearer'},
          3: {'6723592': 'Tenet', '1099212': 'Twilight', '1877830': 'The Batman'}}

现在,我想要 return 一个字典,该字典具有嵌套字典中所有字典的公共键值对,在这种情况下它将是

--> 1877830 The Batman

因为它是所有 3 个嵌套词典中唯一通用的词典。

我似乎想不通的是如何比较这些词典:

#mov is where Movies will be passed    
def Narrow_down(mov):
      final_list= mov[1]
      for i in final_list.keys():
        for x,y in mov.items(): 
            for key in y:
                if i==key:
                    print(i, "is common ")

您可以迭代外部字典的值,维护一组 key-value 对,这些对是目前看到的所有字典共有的(使用集合交集操作)。然后,您可以使用字典理解将这组 key-value 对翻译成字典:

common_items = None

for inner_dict in Movies.values():
    if common_items is None:
        common_items = set(inner_dict.items())
    else:
        common_items = common_items.intersection(inner_dict.items())

result = {key: value for key, value in common_items}
print(result)

对于给定的电影,这将打印:

{'1877830': 'The Batman'}

你基本上想要获取第一个字典,然后对于下一个字典,只保留第一个字典中也在下一个字典中的键。

一个非常简单的解决方案使用 functools.reduce():

from functools import reduce

# you don't really need the outer dictionary, but if you do, this is list(Movies.values())
movies = [
    {'1060277': 'cloverfield', '1877830': 'The Batman', '0117283': 'The Pallbearer'},
    {'1877830': 'The Batman', '1877321': 'The Yards', '0117283': 'The Pallbearer'},
    {'6723592': 'Tenet', '1099212': 'Twilight', '1877830': 'The Batman'}
]

result = reduce(lambda d1, d2: {k: v for k, v in d1.items() if k in d2 and d2[k] == d1[k]}, movies)

print(result)

结果:

{'1877830': 'The Batman'}

请注意,我将变量命名为 movies - 你应该避免用大写字母命名变量,因为这会导致其他人(也许未来的你)认为它是一个 class 名称。

如果您真的只想要常见的 key-value 对,那么这里是删除具有相同键但此键值不同的 key-value 对的代码:

common_keys: set = None

for _, nested_dict in Movies.items():
    if common_keys is None:
        common_keys = set(nested_dict.keys())
    else:
        common_keys = common_keys.intersection(set(nested_dict.keys()))


# remove key-value pairs with same keys but different values
common_key_value_pairs = {}
common_keys_different_values = set()

for common_key in common_keys:
    for _, nested_dict in Movies.items():
        if common_key in common_key_value_pairs:
            if common_key_value_pairs[common_key] != nested_dict[common_key]:
                common_keys_different_values.add(common_key)
        else:
            common_key_value_pairs[common_key] = nested_dict[common_key]

for key in common_keys_different_values:
    print(f"Key {key} has different values in the respective dicts")
    del common_key_value_pairs[key]
    
print(common_key_value_pairs)

您可以使用字典项的集合交集:

set.intersection(*(set(d.items()) for d in Movies.values()))

输出:{('1877830', 'The Batman')}

作为字典:

dict(set.intersection(*(set(d.items()) for d in Movies.values())))

输出:{'1877830': 'The Batman'}