Alex Rivera | Logout

Efficient way to either create a list, or append to it if one already exists?

Asked 2010-01-12T20:27:13.077
71

I'm going through a whole bunch of tuples with a many-to-many correlation, and I want to make a dictionary where each b of (a,b) has a list of all the a's that correspond to a b. It seems awkward to test for a list at key b in the dictionary, then look for an a, then append a if it's not already there, every single time through the tuple digesting loop; but I haven't found a better way yet. Does one exist? Is there some other way to do this that's a lot prettier?

Edit
Report

2 Answers

101

See the docs for the setdefault() method:

setdefault(key[, default])
If key is in the dictionary, return its value. If not, insert key with a value of default and return default. default defaults to None.

You can use this as a single call that will get b if it exists, or set b to an empty list if it doesn't already exist - and either way, return b:

>>> key = 'b'
>>> val = 'a'
>>> print d
{}
>>> d.setdefault(key, []).append(val)
>>> print d
{'b': ['a']}
>>> d.setdefault(key, []).append('zee')
>>> print d
{'b': ['a', 'zee']}

Combine this with a simple "not in" check and you've done what you're after in three lines:

>>> b = d.setdefault('b', [])
>>> if val not in b:
...   b.append(val)
... 
>>> print d
{'b': ['a', 'zee', 'c']}
answered 2010-01-12T20:42:56.853
6

Use collections.defaultdict

your_dict = defaultdict(list)
for (a,b) in your_list:
    your_dict[b].append(a)
answered 2010-01-12T20:44:58.273

Your Answer