Apologies in advance if this question has already been explored here - I looked at different answers here but couldn't find what I need.
My goal is to create a dictionary like this -- {'a':[10, 9, 10, 10], 'b':[10, 9, 1, 0], 'c':[0, 5, 0, 1], and so on}
What I have is multiple dictionaries with duplicate keys (same keys in every other dictionary), something like this
{'a':10, 'b': 0, 'c': 2}
{'a':7, 'b': 4, 'c': 4}
{'a':4, 'b': 5, 'c': 3}
I have no way of knowing the number of such dictionaries, or if there are keys continuing up to 'f', or a 'g' in them but I know that the keys are duplicated. I've tried defaultdict
but what I get is--
defaultdict(<type 'list'>, {'a': [10]})
defaultdict(<type 'list'>, {'a': [10], 'b': [3]})
defaultdict(<type 'list'>, {'a': [10], 'b': [3], 'c': [0]})
and then the same thing for the next dictionary --
defaultdict(<type 'list'>, {'a': [4]})
defaultdict(<type 'list'>, {'a': [4], 'b': [5]})
defaultdict(<type 'list'>, {'a': [4], 'b': [5], 'c': [1]})
The code I have for the above output is --
d = collections.defaultdict(list)
for k, v in z.iteritems():
d[k].append(v)
c = d.items()
print d
If I do a print c
instead (to print the d.items()
) I get --
[('a', [10])]
[('a', [10]), ('b', [3])]
[('a', [10]), ('c', [0]), ('b', [3])]
which is again repeated for each dictionary. How do I get 1 dict holding all the keys, values --
{'a':[10,0,..], 'b':[4, 3, 4,..], etc.} ?
I should also add that the dicts I have are the result of a for loop and not stored individually in a unique variable.
If I understand correctly your attetion, you are trying to merge various dictionaries. One way using built-ins (I am sure that soon someone will give you a numpy
and collections
answer) could look like this:
ds = [
{'a':10, 'b': 0, 'c': 2},
{'a':7, 'b': 4, 'c': 4},
{'a':4, 'b': 5, 'c': 3} ]
merged = {}
for d in ds:
for k, v in d.items ():
if k not in merged: merged [k] = []
merged [k].append (v)
print (merged)
(Quite verbose for clarity)
EDIT:
After having read your comment stating "The result I want is a list of values/key.", you can use this on the resulting merged dictionary:
print ( [ (v, k) for k, v in merged.items () ] )
This yields:
[([10, 7, 4], 'a'), ([2, 4, 3], 'c'), ([0, 4, 5], 'b')]
Is this what you need?
in_dicts = [{'a':10, 'b': 0, 'c': 2}, {'a':7, 'b': 4, 'c': 4}, {'a':4, 'b': 5, 'c': 3}]
out_dict = {}
for in_d in in_dicts:
for k, v in in_d.iteritems():
out_dict.setdefault(k, []).append(v)
print out_dict
{'a': [10, 7, 4], 'c': [2, 4, 3], 'b': [0, 4, 5]}
Here's one way of thinking about this:
Given a dictionary in Python, you can access the value
by dictionary[key]
.
In your case, the values of the dictionaries are lists.
So you can come up with a function to take a key, see if it already exists in your dictionary, and if it does, just append the value to the dictionary. For example:
Say this is your current dictionary:
d = { 'a':[3, 17], 'b':[2, 4] }
and you have this data to parse:
data0 = { 'a':10, 'b':2, 'c':2 }
Since the key 'a'
already exists, you want to take the value of data0['a']
and append to d
by d['a'].append(data0['a'])
.
Let me know this helps / if you need any further clarification!
Another way to do it is to initialise a dict and then populate it with unique keys across dictionaries, and their corresponding values without overwriting existing values.
Steps:
1. Initialise an empty dict (say key_values
) to store required key - values pairs
2. Iterate through the original list of dicts
3. Yield dicts one at a time
4.
If a key
has not already been added to the key_values
dict, add the key
and add its value
to a list; otherwise, append value
to the value of the existing key (which is a list).
list_of_dicts = [{'a':10, 'b': 0, 'c': 2}, {'a':7, 'b': 4, 'c': 4}, {'a':4, 'b': 5, 'c': 3}]
key_values = {}
for d in list_of_dicts:
for k,v in d.iteritems():
if k in key_values.keys():
key_values[k].append(v)
else:
key_values[k]=[v]
print key_values #prints out: {'a': [10, 7, 4], 'c': [2, 4, 3], 'b': [0, 4, 5]}