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

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

Assuming you're not really tied to lists, defaultdict and set are quite handy.

import collections
d = collections.defaultdict(set)
for a, b in mappings:
    d[b].add(a)

If you really want lists instead of sets, you could follow this with a

for k, v in d.iteritems():
    d[k] = list(v)

And if you really want a dict instead of a defaultdict, you can say

d = dict(d)

I don't really see any reason you'd want to, though.


Use collections.defaultdict

your_dict = defaultdict(list)
for (a,b) in your_list:
    your_dict[b].append(a)

you can sort your tuples O(n log n) then create your dictionary O(n)

or simplier O(n) but could impose heavy load on memory in case of many tuples:

your_dict = {}
for (a,b) in your_list:
    if b in your_dict:
        your_dict[b].append(a)
    else:
        your_dict[b]=[a]

Hmm it's pretty much the same as you've described. What's awkward about that?

You could also consider using an sql database to do the dirty work.


Instead of using an if, AFAIK it is more pythonic to use a try block instead.

your_list=[('a',1),('a',3),('b',1),('f',1),('a',2),('z',1)]

your_dict={}
for (a,b) in your_list:
    try:
        your_dict[b].append(a)
    except KeyError:
        your_dict[b]=[a]

print your_dict