Python: The Dictionary Playbook

I so often come across various kinds of boilerplate code regarding dictionaries in Python, that I decided to show some of it here and share the more concise way of performing the same operations. Presenting: The Dictionary Playbook.


This is a companion discussion topic for the original entry at http://amir.rachum.com/blog/2013/01/02/python-the-dictionary-playbook/

Looks like someone actually learned something from that course

Yeah, thanks for that :)

Instead of Counter(d) in earlier python 2.x you can also use enumerate(d)

I'm a fairly inexperienced developer, so this is very much a curious question not a criticism...

In #3 I would say that the first example is much more readable (ie, instantly obvious what the developers intention is) than the second one, even though the second one may be more compact/concise. Is that just because I'm unfamiliar with it? Is it worth compacting code right down if it hampers the ability for other developers to understand the code fast?

Great post btw, thanks :)

While counter is the natural response for incrementing examples, the collections library in general has a wealth of delightful things like defaultdict that are great for when you want to try to modify a value in a dictionary and you don't know if the value in question already exists.

The collections library is one of the more commonly used libraries (in my case, I wound up there as a result of collections.defaultdict), so I'd say most python devs will run into it eventually. That level of assumed familiarity does come with a small trade-off for devs new to the language, but in this case I don't think there's a serious loss in readability.

enumerate gives an index to each key, it's not really the same.

In #4 "Rockign it out" where does "list" come from?

I think setdefault(key,[]) may construct and throw away the empty list if it's not used, which isn't ideal--probably not a big deal for [], but could be for an a constructor that's slow or has side effects.

And w00t, we all need more defaultdict in our lives.

It can be any callable, and it's called to get a default whenever the a key isn't found: http://docs.python.org/2/libra...

In this case, he's passing in the list type, so it calls Python's built-in list constructor. But it could just as well be the name of another type, built-in (like set) or custom (MyNiftySortedListTypeHooray). You might not want to do this, but it could even be a nontrivial function that does real work (e.g., you could make connection_cache['www.google.com'] either return a cached connection or connect if there is none).

He links to a kind of cool example I hadn't seen before: https://gist.github.com/201225... -- emulating Perl-style autovivification in Python, so you can just set mytree['x']['y']['z'] = 3 without explicitly defining mytree['x'] and mytree['x']['y'] first.

It's a Python builtin, available everywhere.

Sweet. Thanks.

If you don't need to support all versions of Python, 2.7 allows you to do: foos = {x.id: x for x in foo_list}

Note that, for all versions, you don't need to materialize a temporary array in the dict constructor, but can pass an iterator:
array = [1, 2, 3]
dict((e, 2*e) for e in array)

What course?

I've taught a course with similar material in the author's workplace. the material is on github: https://github.com/alonho/cour...

In #4 it is group[key].append(value), not group.append(value)

For #3, if Counter doesn't work for you, defaultdict can help again!
dct = defaultdict(int)

dct[key] += 1

"manually reinsert its modified version to the dictionary": You don't need to reinsert an object that is mutable. You can simply modify it in situ.

Hi, the "one-line tree definition" link does not work for me. Is there an alternative? Thanks!

[Yet another defaultdict fan]