Hi,

I've been trying to use reduce() function to add values in the list of tuples. I'm only interested to add and display the numbers, but I don't know how to access and operate only on the second column(numbers)

I've tried to do it using regular function and then the reduce()

What am I doing wrong?

import functools
list = [("Rachel",19),
("Monica",18),
("Phoebe",17),
("Joey",16),
("Ross",20),
("Chandler",21)]
def func(self):
x = list[0][1]
y = list[1][1]
return x+y
func_x = func(self="")
print(func_x)
ages_added = functools.reduce(lambda x,y:x[1][1]+y[1][1],list)
print(ages_added)

Firstly, the name of the

`list`

should not be named

`list`

because

`list`

is a built-in function.

To get the second values from the tuple, you must iterate over the data.

data = [
("Rachel", 19),
("Monica", 18),
("Phoebe", 17),
("Joey", 16),
("Ross", 20),
("Chandler", 21),
]
for elements in data:
print(elements)
# ("Rachel",19) ...
for elements in data:
print(elements[1]) # print second element
for name, age in data:
print(age)
# but name is not used, so you can assgn it the the thow away variable _
for _, age in data:
print(age)

Or if you want to create a new list only with the second values of the tuples:

from operator import itemgetter
def get(data, index):
getter = itemgetter(index)
return [getter(values) for values in data]
# without itemgetter
def get(data, index):
return [values[index] for values in data]
data = [
("Rachel", 19),
("Monica", 18),
("Phoebe", 17),
("Joey", 16),
("Ross", 20),
("Chandler", 21),
]
ages = get(data, 1)

Thank You
That totally works!

Although what I'm looking for is to use the reduce function to add up all the numbers.

I figured out the way to iterate over the second column...

second_column = (lambda x:x[1])

...but can't find the way to use it in the

functools.reduce()
Anyway, maybe it can't be done

It's certainly possible, but I wouldn't do it due to the asymmetry.

>>> friends
[('Rachel', 19), ('Phoebe', 17), ('Joey', 16), ('Ross', 20), ('Chandler', 21)]
>>> reduce(lambda x,y:x+ y[1], friends, 0)
93

This makes use of the fact that you only need the second element from the new items as they are brought in, but you add it to the entire accumulator. And by initializing the accumulator to 0, it's always present.

Alternatively, instead of returning an int, you can return a tuple with the answer in the second column. Then the addition is natural, but you have to massage the answer when complete.

>>> reduce(lambda x,y:(None, x[1] + y[1]), friends)
(None, 93)

Personally, I'd break the problem down into steps: turn the list of people into just a list of ages (which is a

`map`

or list comprehension) and then add those up (the

`reduce`

).

The third party Tools library has functions that can make these sorts of pipelines read quite nicely:

https://toolz.readthedocs.io/en/latest/a...read_first.

(Jan-05-2023, 06:03 PM)kinimod Wrote: [ -> ]Although what I'm looking for is to use the reduce function to add up all the numbers.

Alternative to bowlofred solution is to stream only age and use lambda to add up:

from functools import reduce
data = [("Rachel",19),
("Monica",18),
("Phoebe",17),
("Joey",16),
("Ross",20),
("Chandler",21)]
total = reduce(lambda x, y: x+y, (age for _, age in data))
# total -> 111

Of course, for adding there is built-in function sum:

sum(age for _, age in data)

Since reading this thread I've been looking for an example where reduce was a better choice than any other python construct. I did not fine any. Every example I found for reduce() could be written shorter and clearer using a comprehension.

from functools import reduce
from time import time
values = [('A', b) for b in range(10000000)]
start = time()
print(reduce(lambda a, b: a + b[1], values, 0))
print(time() - start)
start = time()
print(sum((value[1] for value in values)))
print(time() - start)

Output:

49999995000000
0.7833819389343262
49999995000000
0.7230224609375

The comprehension is even a tiny bit faster.

(Jan-23-2023, 04:23 AM)deanhystad Wrote: [ -> ]Since reading this thread I've been looking for an example where reduce was a better choice than any other python construct. I did not fine any. Every example I found for reduce() could be written shorter and clearer using a comprehension.

I believa that before comprehension came along something like this was quite common:

from functools import reduce
from operator import add
data = range(10000000)
print(reduce(add, data))

const listOfTuples = [

[1, 2],

[3, 4],

[5, 6],

[7, 8],

];

const sum = listOfTuples.reduce((acc, cur) => acc + cur[0] + cur[1], 0);

console.log(sum); // Output: 36

Not great examples. I see why it was demoted from builtins and exiled to functools.