Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid double lookup when updating dictionary integer members

If a dictionary contains something to which you can hold a reference, you can default-or-update it with one dictionary lookup:

d.setdefault('k', []).append(2)

However, modifying dictionary entries in the same manner is not possible if they're numbers:

d.setdefault('k', 0) += 1  # doesn't work

Instead, you need to do two dict lookups, one for read and one for write:

d['a'] = d.get('a', 0) + 1

This doesn't seem like a great idea for dictionaries with a huge number of keys. So, is there a way to do a default-or-update operation on dictionaries containing numbers? Or, phrased another way, what's the most performant way to apply a default-or-update operation on such dictionaries?

like image 959
Reinderien Avatar asked Apr 14 '26 13:04

Reinderien


1 Answers

A quick test suggests that collections.defaultdict is about 2.5 times faster than your double-lookup (tested on Python 2.6):

>>> import timeit
>>> s1 = "d = dict((str(n), 0) for n in range(1000000))"
>>> timeit.repeat("d['a'] = d.get('a', 0) + 1", setup=s1)
[0.17711305618286133, 0.17411494255065918, 0.17812514305114746]
>>> s2 = """
... from collections import defaultdict
... d = defaultdict(int, ((str(n), 0) for n in range(1000000)))
... """
>>> timeit.repeat("d['a'] += 1", setup=s2)
[0.07185506820678711, 0.07294416427612305, 0.12155508995056152]
like image 146
Zero Piraeus Avatar answered Apr 17 '26 02:04

Zero Piraeus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!