如何在Python中比较两个不同字典的键?

时间:2015-03-26 11:24:25

标签: python python-2.7 dictionary

我有两个词典,我想比较相应键的值。例如,如果我有

dict1 = {'a':1, 'b':0, 'c':3}
dict2 = {'a':0, 'b':0, 'c':4}

然后这应该返回False,因为dict2的对应值不能大于dict11的值(dict2 'a'可以正常的值小于dict1的值,但'c'中的dict2的值大于dict1的值。

如果dict2的值未在dict1中列出,则不允许这样做。例如:

dict1 = {'a':1, 'b':0, 'c':3}
dict2 = {'a':0, 'b':0, 'd':2}

(但如果dict1的值为dict2,则可以。换句话说,关于键和值,dict2必须是dict1的子集。

一旦代码捕获到其中一个违规行为,我想立即停止运行所有内容并返回False。

这就是我的尝试:

condition = True #True by default
for letter in dict2:
    if dict2[letter] > dict1[letter] or dict1[letter] == None: 
        condition = False
        break
    break

但是当我遇到KeyError中列出的密钥而不是dict1中的密钥时,我得到dict2

我该如何解决这个问题?

6 个答案:

答案 0 :(得分:6)

我认为你正在寻找这样的东西:

condition = all(k in dict1 and dict2[k] <= dict1[k] for k in dict2)

您在评论中询问如何阅读此内容。这很难回答,因为不是每个人都会以同样的方式看待它。也许如果我告诉你我是如何达到这个表达方式的话可能有所帮助。

我读了你的问题&#34; dict2中的每个键都必须在dict1中,而dict2中的值不能大于dict1&#34;中的值,我重新表达为&#34;对于dict2中的所有k,dict1中的k和dict2 [k]&lt; = dict1 [k]&#34;这似乎是all()函数的明显案例,for移到最后。

答案 1 :(得分:1)

这是一种避免使用try的简单方法。我还包括几个测试用例,所有比较都在compare_2lt1。

# Set 1 violates the comparison in key 'c', too large
dict1_1 = {'a':1, 'b':0, 'c':3}
dict2_1 = {'a':0, 'b':0, 'c':4}

# Set 2 violates the comparison in key 'd', doesn't exist
dict1_2 = {'a':1, 'b':0, 'c':3}
dict2_2 = {'a':0, 'b':0, 'c':2, 'd':5}

# Set 3 is True
dict1_3 = {'a':1, 'b':0, 'c':3}
dict2_3 = {'a':0, 'b':0, 'c':2}

def compare_2lt1(d1, d2):
    for key in d2:
        if key in d1 and d1[key] >= d2[key]:
            continue
        else:
            return False
    return True

def test(d1, d2):
    print d1
    print d2
    print compare_2lt1(d1, d2)
    print "-----"


test(dict1_1, dict2_1)
test(dict1_2, dict2_2)
test(dict1_3, dict2_3)

输出:

{'a': 1, 'c': 3, 'b': 0}
{'a': 0, 'c': 4, 'b': 0}
False
-----
{'a': 1, 'c': 3, 'b': 0}
{'a': 0, 'c': 2, 'b': 0, 'd': 5}
False
-----
{'a': 1, 'c': 3, 'b': 0}
{'a': 0, 'c': 2, 'b': 0}
True
-----

答案 2 :(得分:0)

您可能还想使用defaultdict而不是常规&#39;字典: https://docs.python.org/2/library/collections.html

如果找不到密钥则返回false,并且不会抛出错误。

答案 3 :(得分:0)

尝试修改为

condition = True #True by default
for letter in dict2:
    if letter not in dict1.keys() or dict2[letter] > dict1[letter]: 
        condition = False
        break
    break

答案 4 :(得分:0)

您正在获取keyError,因为没有为字典中没有的键映射值,因此它将给出keyError而不是将未初始化的键值作为&#39; None&#39;因为你在里面检查循环:

if dict2[letter] > dict1[letter] or dict1[letter] == None:

@Duncan在单行理解中写了一个很好的答案, 我只是试图在你尝试的时候重写它,

d1 = { 'a' = 1,'b' = 2, 'c'= 3}
d2 = { 'a' = 2,'b' = 3, 'd'= 4}

key&#39; d&#39;在d1中没有,所以它应该返回False

 condition = True
    for key in d2.keys():
        if not (key in d1.keys() and d2[key] > d1[key]):
            condition = False
            break

现在当你查找条件时,它的值将为False,

答案 5 :(得分:0)

这是你想要的吗?

#Value in dict2 greater than value in dict1 for same key ?
condition1 = sum([dict2[a] > dict1[a] for a in dict2 if a in dict1]) == 0

#keys in dict2 not in dict1
condition2 = [a for a in dict2 if a not in dict1] == []

#The two conditions
condition =  condition1 and condition2 

#Test
if condition:
    print True
print False