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.