user1629366
user1629366

Reputation: 2011

Create a python dictionary with unique keys that have list as their values

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

Answers (3)

ccbunney
ccbunney

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

Lo&#239;c Faure-Lacroix
Lo&#239;c Faure-Lacroix

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

m01
m01

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

Related Questions