Wayne Werner
Wayne Werner

Reputation: 51817

What's the cleanest (most Pythonic) way of creating a dictionary with list values from a sequence?

I have a collection that looks like this:

stuff = [('key1', 1), ('key2', 2), ('key3', 3), 
         ('key1', 11), ('key2', 22), ('key3', 33),
         ('key1', 111), ('key2', 222), ('key3', 333),
         ]
# Note: values aren't actually that nice. That would make this easy.

I want to turn it into a dictionary that looks like this:

dict_stuff = {'key1': [1, 11, 111],
              'key2': [2, 22, 222],
              'key3': [3, 33, 333],
              }

What's the nicest way to convert this data? The first method that comes to mind is:

dict_stuff = {}
for k,v in stuff:
    dict[k] = dict.get(k, [])
    dict[k].append(v)

Is that the cleanest way to do this?

Upvotes: 2

Views: 109

Answers (3)

Amrita Sawant
Amrita Sawant

Reputation: 10913

stuff_dict = {}
for k, v in stuff:
    if stuff_dict.has_key(k):
        stuff_dict[k].append(v)
    else:
        stuff_dict[k] = [v]


print stuff_dict
{'key3': [3, 33, 333], 'key2': [2, 22, 222], 'key1': [1, 11, 111]}

Upvotes: 0

Rafael Barros
Rafael Barros

Reputation: 2881

There is defaultdict in the collections lib.

>>> from collections import defaultdict
>>> dict_stuff = defaultdict(list) # this will make the value for new keys become default to an empty list
>>> stuff = [('key1', 1), ('key2', 2), ('key3', 3), 
...          ('key1', 11), ('key2', 22), ('key3', 33),
...          ('key1', 111), ('key2', 222), ('key3', 333),
...          ]
>>> 
>>> for k, v in stuff:
...     dict_stuff[k].append(v)
... 
>>> dict_stuff
defaultdict(<type 'list'>, {'key3': [3, 33, 333], 'key2': [2, 22, 222], 'key1': [1, 11, 111]})

Upvotes: 1

thefourtheye
thefourtheye

Reputation: 239493

You can make use of dict.setdefault, like this

dict_stuff = {}
for key, value in stuff:
    dict_stuff.setdefault(key, []).append(value)

It says that, if the key doesn't exist in the dictionary, then use the second parameter as the default value for it, otherwise return the actual value corresponding to the key.

We also have a built-in dict class, which helps you deal with cases like this, called collections.defaultdict.

from collections import defaultdict
dict_stuff = defaultdict(list)
for key, value in stuff:
    dict_stuff[key].append(value)

Here, if the key doesn't exist in the defaultdict object, the factory function passed to the defaultdict constructor will be called to create the value object.

Upvotes: 2

Related Questions