Python Forum

Full Version: Adding values with reduce() function from the list of tuples
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
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! Big Grin 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 Think
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.
Pages: 1 2