Reputation: 2011
I want to create a dictionary as following -
{'a':[1, 2, 3, 4, 5], 'b':[1, 3, 5], 'c':[2, 3, 5]}
The way I have implemented it is
mydict = dict()
letters = ['a', 'b', 'a', 'c', 'a']
#please mark the list has multiple occurence of a,
#hence I would want to check if a key with 'a' exists. Please do not advise to make the list unique.
for l in letters:
if not mydict.get(l):
mydict[l] = <values from another place via some filter>
else:
mydict[l].append(<values from another dict>)
Is there a better approach to do this?
Upvotes: 1
Views: 4606
Reputation: 2762
You could use a defaultdict
. (See reference)
from collections import defaultdict
mydict = defaultdict(list)
letters = ['a', 'b', 'a', 'c', 'a']
for l in letters:
mydict[l].append(<some data>)
Upvotes: 0
Reputation: 13600
The solution provided by m01 is cool and all but I believe it's worth mentionning that we can do that with a plain dict object..
mydict = dict()
letters = ['a', 'b', 'a', 'c', 'a']
for l in letters:
mydict.setdefault(l, []).append('1')
the result should be the same. You'll have a default dict instead of using a subclass. It really depends on what you're looking for. My guess is that the big problem with my solution is that it will create a new list even if it is not needed.
The defaultdict
object has the advantage to create a new object only when something is missing. This solution has the advantage to be a simple dict without nothing special.
Edit
After thinking about it, I found out that using setdefault
on a defaultdict
will work as expected. But it's not yet good enough to say that a plain old dict
should be used instead. There are cases where having a dict
is important. To make it short, an invalid key on a dict
will raise a KeyError
. A defaultdict
will return a default value.
As an example, there is the traversal algorithm that stops whenever it catches a KeyError or it traversed a whole path. With a defaultdict
, you'd have to raise yourself the KeyError in case of errors.
Upvotes: 2
Reputation: 9385
Yes, you can use the defaultdict:
Sample code:
»»» from collections import defaultdict
»»» mydict = defaultdict(list)
»»» letters = ['a', 'b', 'a', 'c', 'a']
»»» for l in letters:
....: mydict[l].append('1')
....:
»»» mydict
Out[15]: defaultdict(<type 'list'>, {'a': ['1', '1', '1'], 'c': ['1'], 'b': ['1']})
If you need the content to be initialised to something fancier, you can specify your own construction function as the first argument to defaultdict
. Passing context-specific arguments to that constructor might be tricky though.
Upvotes: 4