Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can you apply an operation directly to arguments within map/reduce/filter?

map and filter are often interchangeable with list comprehensions, but reduce is not so easily swapped out as map and filter (and besides, in some cases I still prefer the functional syntax anyway). When you need to operate on the arguments themselves, though, I find myself going through syntactical gymnastics and eventually have to write entire functions to maintain readability.

I'll use map to keep the illustration unit-test simple, but please keep in mind that real-life use-cases might be harder to express as a list comprehension.

I've found two messy ways to go about it, but nothing I would ever actually use.

[afunc(*i) for i in aniter] == map(afunc, *zip(*aniter))
[afunc(*i) for i in aniter] == map(lambda i: apply(afunc, i), aniter)

Is there any pithy, elegant way to express the right hand side of these expressions?

like image 344
kojiro Avatar asked Jul 09 '12 20:07

kojiro


People also ask

Can we use filter and map together?

JavaScript's Array#map() and Array#filter() functions are great when used together because they allow you to compose simple functions. For example, here's a basic use case for filter() : filtering out all numbers that are less than 100 from a numeric array. This function works fine on an array of numbers.

How do MapReduce and filter functions work?

The functions map(), filter(), and reduce() all do the same thing: They each take a function and a list of elements, and then return the result of applying the function to each element in the list. As previously stated, Python has built-in functions like map(), filter(), and reduce().

What is the difference between map () filter () and reduce ()?

The map() function returns a new array through passing a function over each element in the input array. This is different to reduce() which takes an array and a function in the same way, but the function takes 2 inputs - an accumulator and a current value. So reduce() could be used like map() if you always .

How do you use map and reduce together?

Using reduce and map() together Here's how it's done: Map the array into an array of zeros and ones. Reduce the array of zeros and ones into the sum.


1 Answers

Check out itertools for tools that will make your life easier.

For example, the code you posted is already available as itertools.starmap.

itertools.starmap(afunc, aniter)

From the documentation:

Make an iterator that computes the function using arguments obtained from the iterable. Used instead of imap() when argument parameters are already grouped in tuples from a single iterable (the data has been “pre-zipped”). The difference between imap() and starmap() parallels the distinction between function(a,b) and function(*c). Equivalent to:

def starmap(function, iterable):
   # starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
   for args in iterable:
       yield function(*args)

There are also tons over other goodies hidden in itertools, so I recommend you read through the documentation to see if there is anything else there that you can use. The recipes section also show ways that you can use the functions available in itertools to solve a variety of problems. Even if you can't find a recipe that solves your exact requirements, it's likely that you can use some of the ideas demonstrated as a source of inspiration.

like image 77
Mark Byers Avatar answered Sep 20 '22 03:09

Mark Byers