Sam ([info]l33tminion) wrote,
@ 2008-01-16 17:23:00
Previous Entry  Add to memories!  Tell a Friend!  Next Entry
Current mood: thoughtful
Entry tags:programming

Python Counters and Accumulators
Another post while [gigantic test script] runs (so I can continuer debugging SQL weirdness). Probably worth reading if and only if you're a Python programmer:

So, I just recently discovered the setdefualt function of dict (because I'm slow). Basically, it allows you to replace the common task (given foo = {}):

if not foo.has_key('bar'):
    foo['bar'] = []
foo['bar'].append('baz')
With:
foo.setdefault('bar',[]).append('baz')
This works for sets, too, just replace [] with set() and append with add. On the other hand, this doesn't work with counters (which could be viewed as integer accumulators):
foo.setdefault('bar',0) += 1
For that, you have to use a different idiom:
foo['bar'] = foo.get('bar',0) + 1
Note that this idiom won't work with sets or lists, since add and append return None instead of a self-reference (this may be an argument why certain python methods should return self instead of None, but that's a whole different topic).

Anyways, this whole thing amounts to a minor point of interest, except I sort of would like to use the same idiom for counters and object-based accumulators. It just seems to me that if the first line below works, the second line should too:
foo['bar'] += 1
foo.setdefault('bar',0) += 1
P.S. The collections.defaultdict solves this problem in a pretty smooth way. Note that it takes a function, not a constant, as a parameter:
from collections import defaultdict
foo = defaultdict(0)         # Doesn't work: TypeError
foo = defaultdict(lambda: 0) # Works as expected.. but somewhat ugly
foo = defaultdict(int)       # Nicer, works as expected (int() == 0)
foo['bar'] += 1
foo = defaultdict(list)      # Likewise for this
foo['bar'].append('baz')
foo = defaultdict(set)       # And this
foo['bar'].add('baz')


(Post a new comment)


[info]ferrouswheel
2008-01-16 11:35 pm UTC (link)
Thanks for pointing this out!

In the past I'd been creating sub classes of UserDict to do the defaultdict thing. But then I haven't been programming much lately - and when I do I'm spread over several languages so miss these idioms.

(Reply to this)


[info]kihou
2008-01-17 12:40 am UTC (link)
Yeah, one of the things I miss about 2.5 (Metacarta's a 2.4 shop for now) is defaultdict. The others are mainly any and all, which I just define myself.

(Reply to this)(Thread)

defaultdict for 2.4
[info]paddy3118
2008-01-17 05:58 am UTC (link)
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/523034

- enjoy :-)

(Reply to this)(Parent)


Create an Account
Forgot your login?
Login w/ OpenID
English • Español • Deutsch • Русский…