How to compare two dictionaries using a comprehension?

Viewed 587

I want to create a program which accepts two dictionaries and then outputs two new ones, where the first one is going to contain elements that weren't in d1 but were in d2 and the other one is going to contain d1 and then appended elements from d2 that are not in d1.

Input:

dc1 = {'a': 3, 'b': 4, 'c': 5, 'd': 6, 'e': 7, 'f': 8, 'g': 9} 
dc2 = {'e': 20, 'f': 21, 'g': 22, 'h': 23, 'i': 24, 'j': 25, 'k': 26, 'l': 27}

Output:

dc3 = {'h': 23, 'i': 24, 'j': 25, 'k': 26, 'l': 27}
dc4 = {'a': 3, 'b': 4, 'c': 5, 'd': 6, 'e': 7, 'f': 8, 'g': 9, 'h': 23, 'i': 24, 'j': 25, 'k': 26, 'l': 27}

This is the code I've tried running however I can't understand how to properly compare dictionaries using a comprehension and create dc3 and dc4 in just one line. So I'm already facing a syntax error on creating dc3, so I haven't even started working on dc4:

d3 = {v: k for k,v in dic2 for z,x in dic1 if v: k in x:z}
d3

Output:

d3 = {v: k for k,v in dic2 for z,x in dic1 if v: k in x:z}
                                                   ^
SyntaxError: invalid syntax

If anyone can help me out how to properly use a comprehension here, I would really appreciate it.

4 Answers

As you noticed, your syntax is a bit off. I would first assume that where you used in dic2 and in dic1 you meant to use in dic.items() to iterate over key:value pairs. Second, the : can basically only be in the first part of the dict-comp. I guess you meant:

dc3 = {k: v for k,v in dc2.items() if k not in dc1}
dc4 = {**dc1, **dc3}

The creation of dc3 just loops over the key:value pairs in dc2 and only adds them if they are not in dc1.

The creation of dc4 is just a dictionary merge of dc1 and the newly created dc3.

First, you're using comprehensions, not generators.

Second, the simple "in" will handle your comparisons: you don't need nested comprehension syntax.

Try something like this:

{key: val for key, val in dc1.items() if key not in dc2}

Set operations work on dictionary views.

So given:

>>> dc1
{'a': 3, 'b': 4, 'c': 5, 'd': 6, 'e': 7, 'f': 8, 'g': 9}
>>> dc2
{'e': 20, 'f': 21, 'g': 22, 'h': 23, 'i': 24, 'j': 25, 'k': 26, 'l': 27}

You can get what keys are common to both:

>>> dc1.keys() & dc2.keys()
{'e', 'f', 'g'}

And what keys are unique to each:

>>> dc1.keys() - dc2.keys()
{'b', 'a', 'd', 'c'}
>>> dc2.keys() - dc1.keys()
{'i', 'h', 'l', 'k', 'j'}

The same will work for keys and value (so long as the values are immutable; keys are by definition immutable):

>>> dc1.items() - dc2.items()
{('d', 6), ('e', 7), ('a', 3), ('f', 8), ('g', 9), ('c', 5), ('b', 4)}

So your output is:

>>> {k:v for k,v in dc2.items() if k in dc2.keys()-dc1.keys()}
{'h': 23, 'i': 24, 'j': 25, 'k': 26, 'l': 27}

and with Python 3.9:

>>> dc1 | dc2
{'a': 3, 'b': 4, 'c': 5, 'd': 6, 'e': 20, 'f': 21, 'g': 22, 'h': 23, 'i': 24, 'j': 25, 'k': 26, 'l': 27}

Or with earlier:

>>> {**dc1, **dc2}
{'a': 3, 'b': 4, 'c': 5, 'd': 6, 'e': 20, 'f': 21, 'g': 22, 'h': 23, 'i': 24, 'j': 25, 'k': 26, 'l': 27}

I guess what you want is :

d3 = {v: k for k,v in dic6 for z,x in dic5 if k in z}

The : syntax is used for creating dict entries

Related