Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intersection and Difference of two dictionaries

Given two dictionaries, I want to look at their intersction and difference and perform f function on the elements that intersect and perform g on the unique elements, Here's how I found out what the unique and intersecting elements are where d1 and d2 are two dictionaries, How do i print out the d_intersection and d_difference as dictionaries inside a tuple? The output should look something like this ({intersecting keys,values}, {difference keys,values}) for example: given

d1 = {1:30, 2:20, 3:30, 5:80}

d2 = {1:40, 2:50, 3:60, 4:70, 6:90}

The output should be ({1: 70, 2: 70, 3: 90}, {4: 70, 5: 80, 6: 90})

dic = {}
d_intersect = set(d1) & set(d2)
d_difference =  set(d1) ^ set(d2)
for i in d_intersect:
    dic.update({i : f(d1[i],d2[i])})
for j in d_difference:
    dic.update({j : g(d1[j],d2[j])})

Can someone tell me where I was going wrong and why does my code give key error 4?

like image 662
LeafTeaNeko Avatar asked Oct 21 '25 03:10

LeafTeaNeko


2 Answers

You get a KeyError for 4 as ^ looks for the symmetric difference which means keys unique to either, the keys are not in both. You also don't need to create sets, you can use the view object returned from calling .keys

d1 = {1: 30, 2: 20, 3: 30, 5: 80}

d2 = {1: 40, 2: 50, 3: 60, 4: 70, 6: 90}

 # d1.keys() ^ d2 -> {4, 5, 6}, 4, 6 unique to d2, 5 unique to d1.
symm = {k: d1.get(k, d2.get(k)) for k in d1.keys() ^ d2}
inter = {k: d2[k] + d1[k] for k in d1.keys() & d2}

d1.get(k, d2.get(k)) works for the symmetric difference as it catches when we get a unique key from d2.

The code for python2 is slightly different, you would need to replace .keys with .viewkeys to get a view object:

 {k: d1.get(k, d2.get(k)) for k in d1.viewkeys() ^ d2}
 {k: d2[k] + d1[k]  for k in d1.viewkeys() & d2}

To get the just the difference between two sets i.e what is in a but not in b, you need -:

In [1]: d1 = {1: 30, 2: 20, 3: 30, 5: 80}

In [2]: d2 = {1: 40, 2: 50, 3: 60, 4: 70, 6: 90}

In [3]: {k: d2[k] for k in d2.keys() - d1}
Out[3]: {4: 70, 6: 90}

In [4]: {k: d1[k] for k in d1.keys() - d2}
Out[4]: {5: 80}
In [5]: d2.keys() - d1 # in d2 not in d1
Out[5]: {4, 6}

In [6]: d1.keys() - d2 # in d1 not in d2
Out[6]: {5}

In [7]: d1.keys() ^ d2 # unique to either
Out[7]: {4, 5, 6}

The symmetric difference is like doing the union of the differences:

In [12]: d1.keys() - d2 |  d2.keys() - d1
Out[12]: {4, 5, 6}

All the operators are discussed in the python docs, also the wiki page on Set_(mathematics) gives you a good overview.

like image 168
Padraic Cunningham Avatar answered Oct 25 '25 07:10

Padraic Cunningham


Here's one way of doing it, though there may be a more efficient method.

d1 = {1:30, 2:20, 3:30, 5:80}
d2 = {1:40, 2:50, 3:60, 4:70, 6:90}

d_intersect = {} # Keys that appear in both dictionaries.
d_difference = {} # Unique keys that appear in only one dictionary.

# Get all keys from both dictionaries.
# Convert it into a set so that we don't loop through duplicate keys.
all_keys = set(d1.keys() + d2.keys()) # Python2.7
#all_keys = set(list(d1.keys()) + list(d2.keys())) # Python3.3

for key in all_keys:
    if key in d1 and key in d2:
        # If the key appears in both dictionaries, add both values
        # together and place it in intersect.
        d_intersect[key] = d1[key] + d2[key]
    else:
        # Otherwise find out the dictionary it comes from and place
        # it in difference.
        if key in d1:
            d_difference[key] = d1[key]
        else:
            d_difference[key] = d2[key]

Output:

{1: 70, 2: 70, 3: 90}

{4: 70, 5: 80, 6: 90}

like image 24
Green Cell Avatar answered Oct 25 '25 06:10

Green Cell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!