12

It may be a classical question in Python, but I haven't found the answer yet.

I have a list of dictionaries, these dictionaries have similar keys. It looks like this:

 [{0: myech.MatchingResponse at 0x10d6f7fd0, 
   3: myech.MatchingResponse at 0x10d9886d0,
   6: myech.MatchingResponse at 0x10d6f7d90,
   9: myech.MatchingResponse at 0x10d988ad0},
  {0: myech.MatchingResponse at 0x10d6f7b10,
   3: myech.MatchingResponse at 0x10d6f7f90>}]

I would like to get a new dictionary with [0,3,6,9] as keys, and lists of " myech.MatchingResponse" as values.

Of course I can do this using a simple loop but I was wondering if there is a more efficient solution.

Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
lizzie
  • 1,506
  • 1
  • 18
  • 31

4 Answers4

19
import collections

result = collections.defaultdict(list)

for d in dictionaries:
    for k, v in d.items():
        result[k].append(v)
Otto Allmendinger
  • 27,448
  • 7
  • 68
  • 79
2

let's say your list is assigned to a variable called mylist.

mydic = {}
for dic in mylist:
    for key, value in dic.items():
        if key in mydic:
            mydic[key].append(value)
        else:
            mydic[key] = [value]
jamylak
  • 128,818
  • 30
  • 231
  • 230
bigblind
  • 12,539
  • 14
  • 68
  • 123
  • 4
    use `dict.setdefault` or `collections.defaultdict` instead of this! :D – jamylak Jul 12 '12 at 11:22
  • Also this won't work since iterating through a dictionary iterates through it's keys so this, `for key, value in dic`, will raise an error. change to `for key, value in dic.items()`. Edit: I just changed it for you – jamylak Jul 12 '12 at 11:30
  • Why is is so wrong to initialize a dictionary with dic = {} ? – lizzie Jul 12 '12 at 12:08
  • 1
    @lizzie I don't see anything wrong with that. Just don't call it dict or you are shadowing the builtin dict class and you won't be able to access it since your variable has taken the name. – jamylak Jul 12 '12 at 23:18
  • that sounds weird, a variable shadowing it's own type :p – bigblind Jul 13 '12 at 04:19
2

It's possible to do this with dict comprehension as well ... could be one line, but I've kept it as two lines for clarity. :)

from itertools import chain

all_keys = set(chain(*[x.keys() for x in dd]))
print {k : [d[k] for d in dd if k in d] for k in all_keys}

Results in:

{0: ['a', 'x'], 9: ['d'], 3: ['b', 'y'], 6: ['c']}
Maria Zverina
  • 10,863
  • 3
  • 44
  • 61
0

If you have a list of dictionaries with identical keys in each, you can convert these to a dictionary of lists as in the following example, (which some would consider more pythonic than some of the other answers).

d = []
d.append({'a':1,'b':2})
d.append({'a':4,'b':3}) 
print(d)                                                               
[{'a': 1, 'b': 2}, {'a': 4, 'b': 3}]

newdict = {}
for k,v in d[0].items():
    newdict[k] = [x[k] for x in d]

print(newdict)
{'a': [1, 4], 'b': [2, 3]}
vschmidt
  • 63
  • 7
  • `If you have a lists of dictionaries with identical keys`. Which is explicitly ***not*** the case in the question that was actually asked. So, this is an answer to a different question? I propose a shorter answer; `42`, which is *also* an answer to a different question. – MatBailie Nov 20 '21 at 13:02