PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, November 3, 2022

[FIXED] How can I reduce an operation with a subscript?

 November 03, 2022     lambda, python, reduce     No comments   

Issue

expenses = [
    ('Dinner', 80),
    ('Car repair', 120),
    ('csgo skins', 200)
]

# Version with for-loop
sum = 0
for expense in expenses:
    sum += expense[1]
print(sum)

# Version using lambda+reduce
sum2 = reduce((lambda a, b: a[1] + b[1]), expenses)
print(sum2)

I'm trying to obtain, with lambda and reduce, the same result that I had with the for-loop version.

If the expenses list contains only 2 items, everything works fine, but if I add more I get this error:

Traceback (most recent call last):
  File "r:\Developing\_Python\lambda_map_filter_reduce.py", line 44, in <module>
    sum2 = reduce((lambda a, b: a[1] + b[1]), expenses)
  File "r:\Developing\_Python\lambda_map_filter_reduce.py", line 44, in <lambda>
    sum2 = reduce((lambda a, b: a[1] + b[1]), expenses)
TypeError: 'int' object is not subscriptable

What is the correct way of doing this?


Solution

Recall that reduce calls itself with the result from the previous reduce operation as its first argument. So a[1] no longer makes sense because on the second and subsequent iterations, a is the sum returned from the previous iteration.

You can painfully get around this with an explicit special case, of course; or, you can pass in a sequence which removes this obstacle:

from operator import itemgetter
...
sum2 = reduce(
   lambda a, b: a + b,
   map(itemgetter(1), expenses))
print(sum2)

itemgetter is a convenience function for fetching an item at a particular subscript. So, we are basically passing x[1] for x in expenses to reduce instead of the original list.

Chaining transformations like this is one of the cornerstones of functional programming. The paradigm gently nudges you to rethink your problem into simple operations which fit together elegantly.

Demo: https://ideone.com/KnqksZ

As pointed out by @deceze, you could further prettify this;

from operator import add, itemgetter
...
sum2 = reduce(add, map(itemgetter(1), expenses))
print(sum2)

In still other words, the map part of map+reduce should produce a transformation of the input which is suitable for reduce.



Answered By - tripleee
Answer Checked By - Robin (PHPFixing Admin)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing