Idiomatic Python for incrementing pairs

Peter Otten __peter__ at web.de
Sat Jun 8 02:47:43 EDT 2013


Tim Chase wrote:

> On 2013-06-07 23:46, Jason Swails wrote:
>> On Fri, Jun 7, 2013 at 10:32 PM, Tim Chase
>> >   def calculate(params):
>> >     a = b = 0
>> >     if some_calculation(params):
>> >       a += 1
>> >     if other_calculation(params):
>> >       b += 1
>> >     return (a, b)
>> >
>> >   alpha = beta = 0
>> >   temp_a, temp_b = calculate(...)
>> >   alpha += temp_a
>> >   beta += temp_b
>> >
>> > Is there a better way to do this without holding each temporary
>> > result before using it to increment?
>> 
>> alpha = beta = 0
>> alpha, beta = (sum(x) for x in zip( (alpha, beta),
>> calculate(...) ) )
> 
> Yeah, I came up with something similar, but it was so opaque I fell
> back to the more readable version I had above.  With only the two
> variables to increment in this case, the overhead of duplicating code
> doesn't seem as worth it as it might be if there were umpteen
> counters being returned as a tuple and umpteen corresponding
> variables being updated (at which point, it might make more sense to
> switch to another data structure like a dict).  Ah well.  Glad to see
> at least I'm not the only one stymied by trying to make it more
> pythonic while at least keeping it readable.
> 
> -tkc

You can hide the complexity in a custom class:

>>> class T(tuple):
...     def __add__(self, other):
...             return T((a+b) for a, b in zip(self, other))
... 
>>> t = T((0, 0))
>>> for pair in [(1, 10), (2, 20), (3, 30)]:
...     t += pair
... 
>>> t
(6, 60)

(If you are already using numpy you can do the above with a numpy.array 
instead of writing your own T.)




More information about the Python-list mailing list