How do I sum the first value in each tuple in a list of tuples in Python?
Asked Answered
L

7

47

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]

I have a feeling there must be a more Pythonic way.

Lannielanning answered 12/3, 2009 at 10:37 Comment(1)
Ben if you're still around, would you consider accepting SilentGhost's answer instead of mine?Emylee
E
83

In modern versions of Python I'd suggest what SilentGhost posted (repeating here for clarity):

sum(i for i, j in list_of_pairs)

In an earlier version of this answer I had suggested this, which was necessary because SilentGhost's version didn't work in the version of Python (2.3) that was current at the time:

sum([pair[0] for pair in list_of_pairs])

Now that version of Python is beyond obsolete, and SilentGhost's code works in all currently-maintained versions of Python, so there's no longer any reason to recommend the version I had originally posted.

Emylee answered 12/3, 2009 at 10:39 Comment(0)
V
47
sum(i for i, j in list_of_pairs)

will do too.

Vegetarian answered 12/3, 2009 at 10:43 Comment(6)
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 anywayEmylee
+1: prefer this -- tuples have a fixed size and you usually know what the size is.Cathepsin
I like this approach, too. But Davids solution works with n-tuples, too, which might be preferable, depending on the actual problem.Outrank
I should probably note that this code is about 15% faster than the one from accepted answer.Vegetarian
i and j should be replaced with first and second ;)Cassidy
i and j are fine. If I had to type first and second for every sequence iteration, I'd have bleeding stumps for fingers within a man-month.Acerb
R
24

I recommend:

sum(i for i, _ in list_of_pairs)

Note:

Using the variable _(or __ to avoid confliction with the alias of gettext) instead of j has at least two benefits:

  1. _(which stands for placeholder) has better readability
  2. pylint won't complain: "Unused variable 'j'"
Rabinowitz answered 21/4, 2012 at 3:24 Comment(0)
O
6

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))

Note that itertools.imap() is available in Python >= 2.3. So you can use a generator based approach there, too.

Outrank answered 12/3, 2009 at 10:52 Comment(5)
Not really faster than the other two solutions.Lactose
Speed is always good, and should at least be mentioned in the answers.Lactose
Then I suggest a solution in C or Assembler.Outrank
The cases for this approach are clearly laid out in the first sentence of the answer.Outrank
You've got a syntax error here – albeit an extremely minor syntax error. The last line should be suffixed by an additional ")" delimiter.Acerb
R
4

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
Rudie answered 12/3, 2009 at 11:19 Comment(2)
mmm, 'zip' object has no attribute 'next'.Vegetarian
it does have attribute next, howeverVegetarian
B
0

Below is sample code, you can also specify the list range.

def test_lst_sum():
    lst = [1, 3, 5]
    print sum(lst)  # 9
    print sum(lst[1:])  # 8

    print sum(lst[5:])  # 0  out of range so return 0
    print sum(lst[5:-1])  # 0

    print sum(lst[1: -1])  # 3

    lst_tp = [('33', 1), ('88', 2), ('22', 3), ('44', 4)]
    print sum(x[1] for x in lst_tp[1:])  # 9
Bellay answered 27/12, 2017 at 6:55 Comment(0)
S
-2
s,p=0,0
for i in l:
  s=s+i[0]
  p=p+i[1]
print(tuple(s,p))
Scallop answered 4/3, 2020 at 14:35 Comment(1)
Please add some explanation to your answer such that others can learn from itRind

© 2022 - 2024 — McMap. All rights reserved.