简体   繁体   中英

How to compare keys of two different dictionaries in Python?

I have two dictionaries and I want to compare the values of the corresponding keys. For example, if I have

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

then this should return False because dict2 can't have a corresponding value larger than that of dict11 (it was okay in dict2 that 'a' had a smaller value than that of dict1 , but not okay that 'c' in dict2 had value larger than that of dict1 ).

Also it is not allowed if dict2 has a value that is not listed in dict1 . For instance:

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

(But it is okay if dict1 has values that dict2 does not). In other words, dict2 has to be a subset of dict1 in regards to both keys and values.

As soon as the code catches one of these violations, I want to immediately stop everything from running and just return False.

This is what I tried:

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

But I get a KeyError when I run into a key that's listed in dict1 and not in dict2 .

How do I fix this?

I think you are looking for something like this:

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

You asked in the comments how to read this. That's difficult to answer because not everyone would look at it the same way. Perhaps if I tell you how I got to that expression it may help.

I read your question as saying "every key in dict2 must be in dict1, and the value in dict2 must not be greater than the value from dict1", which I re-expressed as "for all k in dict2, k in dict1 and dict2[k] <= dict1[k]" which seemed a clear case for the all() function, and the for move to the end.

Here is a simple approach that avoids using try except. I also included a couple test cases, all of the comparison is in 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)

Output:

{'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
-----

You may also want to use a defaultdict instead if a 'regular' dict: https://docs.python.org/2/library/collections.html

It just returns false if the key is not found, and doesn't throw an error.

Try modifying to

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

you are getting keyError, because there is no value mapped for a key which is not there in the dictionary, so it will give keyError instead of taking the uninitialized key value as 'None' as you are checking inside for loop:

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

@Duncan has written a great answer in single line comprehension, I am just trying to rewrite it as you attempted it,,

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

key 'd' is not there in d1 so, it should return False

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

now when you look for condition its value would be False,

Is it what you want ?

#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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM