tags:

views:

1040

answers:

4

Hi,

I have a list of tuples (always pairs) like this:

[(0, 1), (2, 3), (5, 7), (2, 1)]

I'd like to find the sum of the first items in each pair, i.e.:

0 + 2 + 5 + 2

How can I do this in python? At the moment I'm iterating through the list:

sum = 0
for pair in list_of_pairs:
   sum += pair[0]

but I have a feeling there must be a more pythonic way.

Thanks,

Ben

+15  A: 
sum(pair[0] for pair in list_of_pairs)
David Zaslavsky
That did the trick! Thanks.
Ben
SilentGhost's answer is good too, and looks a little nicer IMO, but evidently it's not compatible with older versions of Python (2.3 in my case)...
David Zaslavsky
I removed the square brackets, because they make it slower as python creates the list first. sum() works just fine with iterators.
Georg
gs, you broke the code in the same way David mentioned SilentGhost's code didn't work. You turned the list comprehension into a generator expression (not an iterator), which didn't exist until Python 2.4.
Tim Lesher
+8  A: 
sum(i for i, j in list_of_pairs)

will do too.

SilentGhost
I thought so at first, but when I tried that in the quickest Python I could access it raised a syntax error :-( Turns out I was testing on Python 2.3, though... +1 anyway
David Zaslavsky
+1: prefer this -- tuples have a fixed size and you usually know what the size is.
S.Lott
I like this approach, too. But Davids solution works with n-tuples, too, which might be preferable, depending on the actual problem.
unbeknown
I should probably note that this code is about 15% faster than the one from accepted answer.
SilentGhost
+2  A: 

If you have a very large list or a generator that produces a large number of pairs you might want to use a generator based approach. For fun I use itemgetter() and imap(), too. A simple generator based approach might be enough, though.

import operator
import itertools
idx0 = operator.itemgetter(0)
list_of_pairs = [(0, 1), (2, 3), (5, 7), (2, 1)]
sum(itertools.imap(idx0, list_of_pairs)

Edit: itertools.imap() is available in Python 2.3. So you can use a generator based approach there, too.

unbeknown
Not really faster than the other two solutions.
Georg
I can't read read anything about speed in the question.
unbeknown
Speed is always good, and should at least be mentioned in the answers.
Georg
Then I suggest a solution in C or Assembler.
unbeknown
The cases for this approach are clearly laid out in the first sentence of the answer.
unbeknown
+1  A: 

Obscure (but fun) answer:

>>> sum(zip(*list_of_pairs)[0])
9

Or when zip's are iterables only this should work:

>>> sum(zip(*list_of_pairs).__next__())
9
Ali A
doesn't work for py3k: zip objects are unsubscriptable
SilentGhost
.next() should work fine in that case
Ali A
mmm, 'zip' object has no attribute 'next'.
SilentGhost
it does have attribute __next__, however
SilentGhost
Ok, thanks, but that's weird. Sorry I am not up on 3k.
Ali A