Sunday, 15 October 2017

Combining Sets and Dictionaries

In a previous post I mentioned that you can convert lists and tuples into sets. I didn't mention dictionaries, because I wasn't sure if you could.
The answer seems to be "Not directly. But there are work-arounds".

Here is a script (with heavy commenting) that I wrote to see if I could use sets to do set-like operations on dictionaries.
#!/usr/bin/python3
dic_alpha = {1:'Alice', 2:'Bob', 3:'Charlie', 4:'Dave', 5:'Eric'}
dic_beta = {4:'Dave', 5:'Eric', 6:'Fiona', 7:'George', 8:'Hermione'}
set_alpha = set(dic_alpha.keys()) # creates a set from the keys of dic_alpha
print ('set_alpha is', set_alpha)
set_beta = set(dic_beta.keys())
print ('set_beta is', set_beta)
set_delta = set_alpha & set_beta # set_delta is the intersection
dic_gamma = dic_alpha
dic_gamma.update(dic_beta) # dic_gamma is a union of both dictionaries
print ('dic_gamma', dic_gamma)
dic_delta = {} # creates new empty dictionary
for key in set_delta:
    dic_delta[key] = dic_gamma[key] # creates new element in dic_delta
    #using dic_gamma to find the values for each key
print ('dic_delta is now', dic_delta) # dic_delta is now the intersection
#of the two dictionaries dic_alpha and dic_beta
 And here is the output:
 RESTART: C:/Users/John/Dropbox/Misc Programming/Python/python3/test08_dict_set.py
set_alpha is {1, 2, 3, 4, 5}
set_beta is {4, 5, 6, 7, 8}
dic_gamma {1: 'Alice', 2: 'Bob', 3: 'Charlie', 4: 'Dave', 5: 'Eric', 6: 'Fiona', 7: 'George', 8: 'Hermione'}
dic_delta <class 'dict'>
dic_delta is now {4: 'Dave', 5: 'Eric'}

>>>

 To be honest, I don't know if there is a cleaner, more efficient way of doing this.
Actually, if you just want the intersection and you are not interested in more in-depth set operations, this is a simpler way:

#!/usr/bin/python3
dic_alpha = {1:'Alice', 2:'Bob', 3:'Charlie', 4:'Dave', 5:'Eric'}
dic_beta = {4:'Dave', 5:'Eric', 6:'Fiona', 7:'George', 8:'Hermione'}

dic_delta = {}
for elem in dic_alpha:
    if elem in dic_beta:
        dic_delta[elem] = dic_alpha[elem]
print ('dic_delta is now', dic_delta)

and this does not actually use sets at all. It simply checks if any key in the first dictionary is also in the second dictionary. If so, the key and its corresponding value are added to the new dictionary, dic_delta.

One thing to be wary of here is that both scripts only check if keys are the same. It does not compare values. This means if the two dictionaries have the some of the same keys but those keys hold different values, you need to be careful which values you end up with.
In the first script the lines
dic_gamma = dic_alpha
dic_gamma.update(dic_beta) 
means that if any keys are shared between dic_alpha and dic_beta, the values from dic_beta will overwrite the ones in dic_gamma, inherited from dic_alpha
Whereas with the second one, the values are simply referenced from dic_alpha, as in the line
dic_delta[elem] = dic_alpha[elem]

No comments:

Post a Comment