[Tutor] Merging dictionaries

Kent Johnson kent37 at tds.net
Wed Aug 6 23:01:50 CEST 2008


On Wed, Aug 6, 2008 at 3:59 PM, Norman Khine <norman at khine.net> wrote:

> So far I have an output which puts in a list all the user's responses, such as
>
> responses = [{'a1': [1], 'a2': [1, 2, 3]}, {'a1': [0], 'a2': [0, 1, 3]} .... ]
>
> Is this an efficient way to do this, say for example I have 1000's of responses?

It's OK, though if you just want the counts, as you create below, you
might want to accumulate them directly.

> What is the best way to append value items of dictionaries, such that:
>
> responses = [{'a1': [1], 'a2': [1, 2, 3]}, {'a1': [0], 'a2': [0, 1, 3]}]
>
> is transformmed into:
>
> answered = {'a1': [0, 1], 'a2': [1, 2, 3, 0, 1, 3]}

collections.defaultdict is very useful when you want to accumulate
dictionary values of any kind. When you look up a key in a
defaultdict, if the key is not found, a default value is supplied.
Thus you don't have to distinguish the first appearance of a key from
subsequent appearances.

The other thing you need is list.extend(), which adds the elements of
one list to the end of another.

In [1]: from collections import defaultdict
In [2]: responses = [{'a1': [1], 'a2': [1, 2, 3]}, {'a1': [0], 'a2': [0, 1, 3]}]
In [3]: answered = defaultdict(list)
In [5]: for response in responses:
   ...:     for q, a in response.items():
   ...:         answered[q].extend(a)

In [6]: answered
Out[6]: defaultdict(<type 'list'>, {'a1': [1, 0], 'a2': [1, 2, 3, 0, 1, 3]})

> And finally, what is the simplest way to count the nummber of occurances, so
> that:
>
> answered = {'a1': [0, 1], 'a2': [1, 2, 3, 0, 1, 3]}
>
> returns
>
> totals = {'a1': [{0: 1, 1: 1}], 'a2': [{0: 1, 1: 2, 2: 1, 3: 2}]}

Again, defaultdict to the rescue:

In [8]: totals = {}
In [10]: for q, answers in answered.items():
   ....:     counts = totals[q] = defaultdict(int)
   ....:     for a in answers:
   ....:         counts[a] += 1

In [11]: totals
Out[11]:
{'a1': defaultdict(<type 'int'>, {0: 1, 1: 1}),
 'a2': defaultdict(<type 'int'>, {0: 1, 1: 2, 2: 1, 3: 2})}

Kent


More information about the Tutor mailing list