Question

I have 2 dictionary which contain the same keys but the value pairs are different. Let's make dictA and dictB represent the two dictionaries in question.

dictA = {'key1':'Joe', 'key2':'Bob'}
dictB = {'key1':'Smith', 'key2':'Johnson'}

Currently, I am creating a new dictionary based the common occurring keys through a nested if statement. In doing so, the values that share a key are contained within a list, in the new dictionary. See this done below:

dictAB = {}  # Create a new dictionary

# Create a list container for dictionary values
for key in dictA.keys():
    dictAB[key] = []

# Iterate through keys in both dictionaries
# Find matching keys and append the respective values to the list container
for key, value in dictA.iteritems():
    for key2, value2 in dictB.iteritems():
        if key == key2:
            dictAB[key].append(value)
            dictAB[key].append(value2)
        else:
            pass

How can this be made into a more clean structure using python dictionary comprehension?

Was it helpful?

Solution

Use sets or key views (python 2.7):

dictAB = {k: [dictA[k], dictB[k]] for k in dictA.viewkeys() & dictB.viewkeys()}

Before 2.7:

dictAB = dict((k, [dictA[k], dictB[k]]) for k in set(dictA) & set(dictB))

In python 3, you can use the .keys method for such operations directly, as they are implemented as views:

dictAB = {k: [dictA[k], dictB[k]] for k in dictA.keys() & dictB.keys()}

Demo (python 2.7):

>>> dictA = {'key1':'Joe', 'key2':'Bob'}
>>> dictB = {'key1':'Smith', 'key2':'Johnson'}
>>> dictAB = {k: [dictA[k], dictB[k]] for k in dictA.viewkeys() & dictB.viewkeys()}
>>> print dictAB
{'key2': ['Bob', 'Johnson'], 'key1': ['Joe', 'Smith']}

The & operator on either two sets or on a dict view creates the intersection of both sets; all keys that are present in both sets.

By using an intersection of the keys, this code will work even if either dictA or dictB has keys that do not appear in the other dictionary. If you are absolutely sure the keys will always match, you could just iterate over either dict directly without the intersection:

dictAB = {k: [dictA[k], dictB[k]] for k in dictA}

OTHER TIPS

dictAB = { key: [dictA[key],dictB[key]] for key in dictA if key in dictB }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top