Search code examples
pythonlambdatuplesreduce

Error: 'int' object is not subscriptable - when using lambda in reduce function


When running the following code, I get the following Error:

Traceback (most recent call last):
  File "/Users/crosseyedbum/Documents/Visual Studio Code/Fundamentals of Python_5.py", line 127, in <module>
    sumo = reduce(lambda a, b : a[1] + b[1], exp)
  File "/Users/crosseyedbum/Documents/Visual Studio Code/Fundamentals of Python_5.py", line 127, in <lambda>
    sumo = reduce(lambda a, b : a[1] + b[1], exp)
TypeError: 'int' object is not subscriptable

I am attempting to sum the integers in each tuple and set the value to sumo.

from functools import reduce

exp = [
    ('Dinner', 80), ('Car repair', 120), ('Netflix', 30), ('Rocket Fuel', 32)
] #stored as tuples
sumo = reduce(lambda a, b : a[1] + b[1], exp)
print(sumo)

OUTPUT:

200

However, the following code runs to sum the integers to 200 just fine. Can someone explain this to me. Or am I only able to use this method with a max of two items in the list**

If someone can explain to a beginner why this is behaving the way it is, I would greatly appreciate it.

I added tuples to my list and expected the code to continue to add the index one, but I only seem to be able to run the code with two items in my list max. That doesn't make any sense to me. The error makes no sense to me, and even less sense why the number of tuples in the list would cause it not work.


Solution

  • The issue is that the a parameter to your lambda function is not what you think it is.

    From the functools.reduce docs:

    The left argument, x, is the accumulated value and the right argument, y, is the update value from the iterable

    In your case, x is a and y is b due to how you named your parameters. So, a is not a tuple, it is the sum. If you don't provide a default start value, the initial accumulated value will be the first value in the iterator (('Dinner', 80) in your case). Because you cannot add integers and tuples, you get an error. Instead, pass a third parameter that will be the default (use an integer, like 0). Try this code:

    from functools import reduce
    
    exp = [
        ('Dinner', 80), ('Car repair', 120), ('Netflix', 30), ('Rocket Fuel', 32)
    ]
    sumo = reduce(lambda a, b: a + b[1], exp, 0)
    print(sumo)  # => 262