如果两个词典的键相等,则使用两个值执行操作并移至新词典(python)

时间:2017-06-19 21:30:28

标签: python loops dictionary compare

我有两个词典,如下:

d1 = {'red':10, 'blue':20, 'green':30, 'yellow':40}
d2 = {'red':1, 'blue':2, 'green':3}

我想浏览d1中的每个项目,看看该键是否与d2中的键匹配。如果是这样,我想从d1键中减去d2键,并将新的键/值对移动到新的字典中,从而产生:

d3 = {'red':9, 'blue':18, 'green':27, 'yellow':40}

我编写了以下脚本来执行此操作:

for x, y in d1.items():
    for a, b in d2.items():
        if x == a:
            d3[x] = (y-b)
        elif x not in d2.items():
            d3[x] = y

这样可行,但是当我尝试在两个包含数千个项目的词典中使用它时,该功能永远不会完成。我想这太慢了。

你能推荐一种更好的方法吗?非常感谢。

3 个答案:

答案 0 :(得分:7)

是的,你让事情变得太复杂,只需使用字典理解

{k:v1-d2.get(k,0) for k,v1 in d1.items()}

这将产生:

>>> {k:v1-d2.get(k,0) for k,v1 in d1.items()}
{'red': 9, 'blue': 18, 'green': 27, 'yellow': 40}

代码的工作原理如下:字典理解将遍历items() d1k密钥和v1 d1的值kv1-d2.get(k,0)

相关联

然后,对于每个此类键值对,我们会将k与结果字典中的键d2.get(k,0)相关联。 k的目标是获取与0相关联的值,如果字词中的不是,则会返回d1

算法运行 - 给定字典查找可以在 O(1)中进行(不保证,但非常可能) - 在 O(n)中使用 n use_frameworks!中的元素数量,速度相当快。

答案 1 :(得分:3)

您可以将dict理解与if-else语句一起使用:

d1 = {'red':10, 'blue':20, 'green':30, 'yellow':40}
d2 = {'red':1, 'blue':2, 'green':3}

new_dict = {a:b-d2[a] if a in d2 else b for a, b in d1.items()}

输出:

{'blue': 18, 'green': 27, 'red': 9, 'yellow': 40}

答案 2 :(得分:2)

只是为了记录(因为我发现词典理解非常优雅)你也可以使用collections.Counter(这也很漂亮)来完成这项任务:

In [1]: from collections import Counter

In [2]: d1 = {'red':10, 'blue':20, 'green':30, 'yellow':40}
   ...: d2 = {'red':1, 'blue':2, 'green':3}
   ...: 

In [3]: A = Counter(d1)

In [4]: B = Counter(d2)

In [5]: A - B
Out[5]: Counter({'blue': 18, 'green': 27, 'red': 9, 'yellow': 40})

正如@WillemVanOnsem的评论所指出的,

  

"如果d2中的值高于d1中的相应值,我们将   没有获得负数,但关键将消失:一个计数器   通常假定计数是自然数"。

然而,有另一个解决方案依赖于Counter使用其substract()方法(仅在python 3.2中引入),但它会修改您的{{1}之一} object(因为它表现为Counter

dict.update()

In [26]: A = Counter({'red':10, 'blue':20, 'green':30, 'yellow':40}) ...: B = Counter({'red':1, 'blue':30, 'green':3}) ...: In [27]: A - B # The 'blue' key disappear Out[27]: Counter({'green': 27, 'red': 9, 'yellow': 40}) In [28]: A.subtract(B) # It handles negative values ... In [29]: A # ...but modify the counter A Out[29]: Counter({'blue': -10, 'green': 27, 'red': 9, 'yellow': 40}) 的主要目的是计算/存储可出售对象的出现次数(因此假设计数是自然数)但它基本上是dict的子类,它提供了几个组合操作它们之间有collections.Counter个对象(加法,减法,并集和交集)。