21

I have structure like this:

structure = [('a', 1), ('b', 3), ('c', 2)]

I would like to sum the integers (1+3+2) using sum() builtin method (in one line).

Any ideas?

David Robinson
  • 74,512
  • 15
  • 159
  • 179
David Silva
  • 1,819
  • 7
  • 25
  • 58

4 Answers4

37
sum(n for _, n in structure)

would work.

David Robinson
  • 74,512
  • 15
  • 159
  • 179
  • 1
    Surprisingly enough, this is marginally faster than my solution (on python 2.7, OS-X 10.5). -- using a list comprehension increases the speed here by almost 50% (for this small example). – mgilson Aug 31 '12 at 15:38
  • 1
    The only weakness I can think of is that it won't work if one element happens to be `('a', 3, 'extra-data-to-ignore')`, whereas both the explicit index and the `zip` approaches -- even the `reduce` -- generalize a little better that way. I guess in Py3 you could write `sum(b for _, b, *_ in structure)` or something.. – DSM Aug 31 '12 at 15:40
  • @mgilson: took the words out of my mouth, I'd just run the tests myself (Python 2.7, OS-X 10.7). I've read before about how fast tuple unpacking is but it was interesting to see it in action. Might have to do with bound checking in the `x[1]` evaluation. – David Robinson Aug 31 '12 at 15:40
  • FWIW, I'd write this as `sum(n for _, n in structure)` to indicate the first item of each pair wasn't being used. – martineau Aug 31 '12 at 15:41
  • @martineau: I like it. It does look a little obscure, though (like the `_` is a special operator). – David Robinson Aug 31 '12 at 15:42
  • @DavidRobinson -- using `_` for unused elements when unpacking is a pretty well established python convention I think. – mgilson Aug 31 '12 at 15:43
  • 2
    It's a fairly common Python idiom though which many would recognize immediately. – martineau Aug 31 '12 at 15:43
  • @mgilson: I meant for beginners seeing this. If I were a beginner I'd wonder if `_,` were a special operator. – David Robinson Aug 31 '12 at 15:44
  • I've noticed before that `_` for "don't care variables" is a bit controversial. Beginners coming from Prolog or Haskell should be used to it, though :) – Fred Foo Aug 31 '12 at 15:49
  • @DSM: To avoid problems with extra data, one could write `import operator` then `sum(operator.itemgetter(1)(t) for t in structure)`. – martineau Aug 31 '12 at 15:49
  • @DavidRobinson: how can bounds checking matter here? `x, y = xy` does have to check whether `len(xy) == 2`, since otherwise it raises a `ValueError`. – Fred Foo Aug 31 '12 at 15:50
  • 3
    @martineau: you definitely could, but in this case that seems like a *very* roundabout way of writing `t[1]`.. – DSM Aug 31 '12 at 15:51
  • Prefer this answer to the others as it avoids using magic numbers. – mRyan Oct 30 '20 at 09:53
19
sum(x[1] for x in structure)

should work

mgilson
  • 283,004
  • 58
  • 591
  • 667
2

You could do

sum(zip(*structure)[1])
nbro
  • 13,796
  • 25
  • 99
  • 185
Eric
  • 91,378
  • 50
  • 226
  • 356
  • 1
    You could use `sum(map(operator.itemgetter(1),structure)` if you really want to avoid the comprehensions ... (but what's the point really?) – mgilson Aug 31 '12 at 15:17
  • 1
    @DavidRobinson -- This new version with `zip` is marginally slower than our answers on python2.7 (OS-X 10.5). – mgilson Aug 31 '12 at 15:47
2

Using a functional style, you could do

reduce(lambda x,y:x+y[1], structure,0)
nbro
  • 13,796
  • 25
  • 99
  • 185
John Wang
  • 4,394
  • 7
  • 33
  • 49
  • 1
    Just a hint, functional programming methods almost got removed from `Python 3` reduce isn't event loaded by default anymore. So list comprehensions should be preferred in this case – user1767754 Dec 03 '17 at 06:56