简体   繁体   中英

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?

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.

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]})
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]}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM