Adam Tomjack wrote:
> I'd write it like this:
> 
>    bin = {}
>    for start, end, AS, full in heard:
>       week = int((start-startDate)/aWeek)
>       counters = bin.setdefault(week, [0, 0])
>       if full:
>          counters[0] += 1
>       else:
>          counters[1] += 1
> 
>    for week, (times_full, times_not_full) in bin.iteritems():
>       print ...
> 
> Seriously, use setdefault() as often as you can.  It may be a little 
> awkward at first, but after a little bit, you instantly know what it 
> means.  It takes out a whole if/else statement which will make your code 
> smaller and more readable at the same time.

However, you should be aware that it can make your code slower.  If the 
default value is expensive to create,

     value = dct.setdefault(key, expensive_func())

will often be slower and/or more memory intensive than

     try:
         value = dct[key]
     except KeyError:
         value = expensive_func()

or

     if key in dct:
         value = dct[key]
     else:
         value = expensive_func()

Personally, I waver back and forth between using setdefault.  It's kind 
of handy, but it never reads quite right.  While I've used it often 
enough to grok it pretty quickly, it's still consumes more of my mental 
processing than some other approaches.

I also tend to agree with the assessment[1] (I believe due to Raymond 
Hettinger) that setdefault is poorly designed, and should instead set a 
default value for the entire dictionary, e.g. so that you could do:

     counts = {}
     counts.setdefault(value=0)
     for elem in data:
         counts[elem] += 1

Unfortunately, this is pretty badly backwards incompatible, so I can 
only really hope for this change in Python 3.0 which is still a number 
of years off.

STeVe

[1]http://wiki.python.org/moin/Python3%2e0Suggestions#head-b384410f8b2dc16fd74c9eec764680e428643d73
-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to