Dictionaries and incrementing keys

Steven D'Aprano steve+comp.lang.python at pearwood.info
Tue Jun 14 09:24:05 EDT 2011


On Tue, 14 Jun 2011 10:57:44 +0000, Steve Crook wrote:

> Hi all,
> 
> I've always done key creation/incrementation using:
> 
> if key in dict:
>     dict[key] += 1
> else:
>     dict[key] = 1
> 
> Today I spotted an alternative:
> 
> dict[key] = dict.get(key, 0) + 1
> 
> Whilst certainly more compact, I'd be interested in views on how
> pythonesque this method is.

Either version is perfectly fine. There's no reason to avoid either other 
than personal preference.

The "if key in dict" version does up to three item lookups (first to see 
if the key is in the dict, then to fetch the value, then to assign it), 
the version with dict.get only does two.

If the key has an expensive hash function, the version using dict.get 
will be much faster:

>>> key = ("abcdefgh"*10000, 5**30, frozenset(range(10000))) * 30
>>>
>>> from timeit import Timer
>>>
>>> t1 = Timer("""if key in d:
...     d[key] += 1
... else:
...     d[key] = 1
... """, "from __main__ import key; d = {key: 0}")
>>>
>>> t2 = Timer("d[key] = d.get(key, 0) + 1", 
... "from __main__ import key; d = {key: 0}")
>>>
>>> min(t1.repeat())
8.739075899124146
>>> min(t2.repeat())
6.425030946731567

but that will rarely be a problem in practice. For "normal" keys which 
are small strings or ints, the "if key in dict" version will usually be 
faster. Unless there are lots of missing keys, in which case the version 
using dict.get may be faster.

Either way, the difference is unlikely to be significant except for the 
tightest of tight loops. 


-- 
Steven



More information about the Python-list mailing list