13

I have this kind of dictionary of lists, initially empty:

d = dict()

Now the use case is to simply add a value to list under a key, which might be a new or an existing key. I think we have to do it like this:

if key not in d:
    d[key] = list()
d[key].append(value)

This seems awfully tedious and error-prone, needing to write multiple lines (with copy-paste or helper function). Is there a more convenient way?

If there isn't "only one way to do it", and you know it, you can also answer that, and maybe suggest alternative ways to accomplish above, even if they aren't necessarily better.

I looked for duplicate, didn't find, but perhaps I just didn't know to use right keywords.

2
  • 2
    Use a defaultdict? Commented Sep 14, 2018 at 16:43
  • There's the .setdefault method for doing this sort of thing. Commented Sep 14, 2018 at 17:36

3 Answers 3

18

What you want is called a defaultdict, as available in the collections library:

Python2.7: https://docs.python.org/2/library/collections.html#defaultdict-examples

Python3.7: https://docs.python.org/3/library/collections.html#collections.defaultdict

Example:
>>> from collections import defaultdict
>>> s = [('yellow', 1), ('blue', 2), ('yellow', 3), ('blue', 4), ('red', 1)]
>>> d = defaultdict(list)
>>> for k, v in s:
...     d[k].append(v)
...
>>> sorted(d.items())
[('blue', [2, 4]), ('red', [1]), ('yellow', [1, 3])]
Sign up to request clarification or add additional context in comments.

Comments

12

d[key] = d.get(key, []) + [value]

to explain
d.get method returns value under the key key and if there is no such key, returns optional argument (second), in this case [] (empty list)

then you will get the list (empty or not) and than you add list [value] to it. this can be also done by .append(value) instead of + [value]

having that list, you set it as the new value to that key

e.g.

d = {1: [1, 2]}
d[1] = d.get(1, []) + [3]
# d == {1: [1, 2, 3]}

d[17] = d.get(17, []) + [8]
# d == {1: [1, 2, 3], 17: [8]}

2 Comments

Why not just d.setdefault(key, []).append(value)?
@schwobaseggl that works, but only for mutable types, it would fail for example dict(str:int)
2
d[key] = list() if (key not in d) else d[key].append(value) 

Uses the ternary operators. And looks somewhat cleaner, however it is still almost identical to your scenario.

I apologize, I wasn't thinking earlier and used standard ternary operators. I changed them to Python ternary operators.

3 Comments

Python does not have ?: operator, does it...? There is the exp1 if cond else exp2 syntax though, you could rewrite the answer using that.
@hyde that is my bad. I used the wrong ternary operators.
I think this doesn't work, still... d[key] = [value] if key not in d else d[key] + [value] should work and cover both cases correctly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.