Reputation: 474
I've created two dictionaries that I wish to combine like this:
dict1 = {'temp1':[1,2,3,4]}
dict2 = {'temp1': [3,4,5],'temp2':[15,16,17]}
dict1.update(dict2)
I was hoping to get this:
dict1 = {'temp1': [1, 2, 3, 4, 5], 'temp2': [15, 16, 17]}
But instead I get this:
dict1 = {'temp1': [3, 4, 5], 'temp2': [15, 16, 17]}
How do I update and filter out duplicates in the lists in the dictionary?
Upvotes: 1
Views: 215
Reputation: 18906
If they can't repeat why not use sets from the start?
dict1 = {'temp1': {1,2,3,4}}
dict2 = {'temp1': {3,4,5},'temp2':{15,16,17}}
for k,v in dict2.items():
dict1[k] = v.union(dict1.get(k,{}))
print(dict1)
Returns:
{'temp1': {1, 2, 3, 4, 5}, 'temp2': {15, 16, 17}}
Upvotes: 0
Reputation: 18208
May not be the most efficient way but one way may be as following:
dict1 = {'temp1':[1,2,3,4]}
dict2 = {'temp1': [3,4,5],'temp2':[15,16,17]}
for key in dict2: # check over keys in dict2
if key in dict1: # if key also exist in dict1 then update values
for v in dict2[key]:
if v not in dict1[key]: # update values only if does not exist
dict1[key].append(v)
else: # if key does not exist copy the values from dict2 for the key
dict1[key] = dict2[key][:]
# dict1 is {'temp2': [15, 16, 17], 'temp1': [1, 2, 3, 4, 5]}
Upvotes: 0
Reputation: 24232
You could create a subclass of dict
that updates lists the way you want:
from collections import UserDict
class ListDict(UserDict):
def __init__(self, data_as_dict):
self.data = data_as_dict
def update(self, other):
for key, sublist in other.items():
self.data[key] = list(set(self.data.get(key, [])) | set(sublist))
dict1 = {'temp1':[1,2,3]}
dict2 = {'temp1': [3,4,5],'temp2':[15,16,17]}
d = ListDict(dict1)
d.update(dict2)
print(d)
# {'temp1': [1, 2, 3, 4, 5], 'temp2': [16, 17, 15]}
Upvotes: 1
Reputation: 3669
Since your dict contains list, we could do something like this-
dict1 = {'temp1':[1,2,3]}
dict2 = {'temp1': [3,4,5],'temp2':[15,16,17]}
for k, v in dict1.iteritems():
try:
dict2[k] = list(set(dict2[k]+v))
except KeyError:
pass
Obviously this method is hacky but solves the problem. You should probably see Jean's answer as this answer is how something can be done but there always are better ways to doing it
Upvotes: 0
Reputation: 140168
dict.update
replaces the values under existing keys, which explains the result you're getting (your values are lists of integers, but the update
method isn't aware of that, and wouldn't know how to merge the data anyway)
Here, you've created a specialized dictionary, with values being list of integers.
What you want is a custom merge function.
I would rebuild a third dict using dict comprehension on the union of the keys, and merging the lists as a set (for unicity) then turn back to list:
dict1 = {'temp1':[1,2,3]}
dict2 = {'temp1': [3,4,5],'temp2':[15,16,17]}
dict3 = {k:list(set(dict1.get(k,[])+dict2.get(k,[]))) for k in set(dict2) | set(dict1)}
print(dict3)
result:
{'temp2': [16, 17, 15], 'temp1': [1, 2, 3, 4, 5]}
The magic of dict1.get(k,[])
is that if the key isn't present, it returns an empty list so +
works and the expression isn't too complex.
the order of the elements isn't guaranteed because of the use of a set
at some point. You could use sorted(set ...)
instead of simple conversion to list
to guarantee that the integer values are sorted.
Upvotes: 2