2017-03-17 51 views
0

我想找出具有多个键值的字典之间的差异。所有我发现的例子,词典都有一个只包含一个值的键。假设你有一个有多个值,如下面的例子键:Python 3:显示字典的键值对之间的差异

pizza_1 = {"toppings": ["cheese", "pepperoni", "mushroom"], 
      "crust": ["deep dish", "hand tossed", "thin"], 
      "size": ["large", "medium", "small"], 
      "price": ["$12.99", "$9.99", "$7.99"]} 

pizza_2 = {"toppings": ["cheese", "pepperoni", "olive"], 
      "crust": ["deep dish", "traditional", "thin"], 
      "size": ["large", "medium", "small"], 
      "brand": ["Domino's", "Pizza Hut", "Little Caesars"]} 

我只想返回在两个库包括键和值两者的差异。无论是pizza_1还是pizza_2的差异,哪个字典都无所谓。我正在寻找下面的例子:

print(differences) 
"toppings": ["mushroom"] 
"crust": ["hand tossed"] 
"price": ["$12.99", "$9.99", "$7.99"] 

我不确定它将如何输出,但想给我的例子寻找。预先感谢您花时间帮助!

-Jeff

+2

到目前为止您尝试过什么? –

+0

钥匙是否总是一样?如果不是,这种密钥会发生什么? –

+0

Hello Martijn,非常感谢您的帮助!从理论上讲,按键应该是相同的,但按键可能不一样。如果钥匙不一样,我希望也可以显示出不同之处。 – jmm5351

回答

2

遍历键的结合,治疗价值as sets并打印set difference

for key in pizza_1.keys() | pizza_2: # union of the dict views 
    difference = set(pizza_1.get(key, [])).difference(pizza_2.get(key, [])) 
    if difference: 
     print(key, list(difference)) 

我使用dict.keys() dictionary view这里提供字典键的结合。 if测试会过滤掉空的结果。

如果你想这是一个字典,你可以产生一个与发电机表情加上一个字典的理解,以避免产生套不止一次:

differences = ((key, list(set(pizza_1.get(key, [])).difference(pizza_2.get(key, [])))) 
       for key in pizza_1.keys() | pizza_2) 
differences = {k: v for k, v in differences if v} 

演示:

>>> for key in pizza_1.keys() | pizza_2: # union of the dict views 
...  difference = set(pizza_1.get(key, [])).difference(pizza_2.get(key, [])) 
...  if difference: 
...   print(key, list(difference)) 
... 
crust ['hand tossed'] 
toppings ['mushroom'] 
price ['$9.99', '$7.99', '$12.99'] 
>>> differences = ((key, list(set(pizza_1.get(key, [])).difference(pizza_2.get(key, [])))) 
...    for key in pizza_1.keys() | pizza_2) 
>>> {k: v for k, v in differences if v} 
{'crust': ['hand tossed'], 'toppings': ['mushroom'], 'price': ['$9.99', '$7.99', '$12.99']} 
+0

您能否以最简单的方式解释这里究竟发生了什么。我仍然在学Python,字典是我需要更好理解的一个领域。为关键pizza_1.keys()| (密钥,[]))差异(pizza_2.get(key,[])) 如果有差异: ) 我不确定set()和get()在这里做什么。此外,如何使用.difference(),因为您有该行等于差异变量。 谢谢, -Jeff – jmm5351

+0

@ jmm5351:我确实尝试将您链接到相关文档(除了'dict。get()')那里;阅读我所包含的链接应该涵盖大部分内容;那么唯一缺少的链接是['dict.get()'](https://docs.python.org/3/library/stdtypes.html#dict.get),它将返回给定键的值,或者如果密钥丢失,则为默认值。 –

+0

@ jmm5351:'pizza_1.keys()| pizza_2'产生一组字典在一起的密钥,所以在一个或另一个字典中的唯一密钥的组合。 'dict.get()'检索该键的值,或者如果在该字典中缺少该值,则改为空列表。 'set(..)。difference(..)'然后取两个列表之间的差异。 –

1

我建议用设置值的字典作为你的输出数据结构。

>>> {k: set(v).difference(pizza_2.get(k, {})) for k, v in pizza_1.items()} 
{'price': {'$9.99', '$7.99', '$12.99'}, 'size': set(), 'toppings': {'mushroom'}, 'crust': {'hand tossed'}} 

结果将为没有差异的键(见大小)保留一个空集。

+0

这在差异字典中给出了一个额外的'size:set()'元素 – Jerfov2

0

什么我做的是通过键循环,并使用列表解析来获得差异(具体而言,pizza_1中的内容不在pizza_2中,如示例输出所示)。

def getDiff(dict1, dict2): 
    diff = {} 

    for key in dict1: 
     if key not in dict2: 
      diff[key] = dict1[key] 
     elif dict1[key] != dict2[key]: 
      diff[key] = [e for e in dict1[key] if e not in dict2[key]] 

    return diff