Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map a list of functions over a list of arguments (Python)

I have a list of functions: listFunc=[g1, g2, g3]. This list is generated with the code below:

def g(y): 
    def f(x):
        return x+y;
    return f; 
listFunc=list(map(g, [1, 2, 3])); 

Now, I have a list of arguments ListArg = [4, 5, 6];

How could I get a result list of [g1(4), g1(5), g1(6), g2(4), g2(5), g2(6), g3(4), g3(5), g3(6)] using map only?

I thought about using the following code:

map(lambda x:x(y), listFunc, ListArg)

But it only gives a result of [g1(4), g2(5), g3(6)].

Thanks,

like image 280
Truevines Truevines Avatar asked Dec 03 '22 23:12

Truevines Truevines


2 Answers

This is a perfect use-case for a list comprehension with two for-clauses:

>>> def g1(x): return 1*x
... 
>>> def g2(x): return 2*x
... 
>>> def g3(x): return 3*x
... 
>>> funcs = [g1,g2,g3]
>>> args = [4,5,6]
>>> [f(a) for f in funcs for a in args]
[4, 5, 6, 8, 10, 12, 12, 15, 18]
>>> 

This is eminently readable and eminently functional - list comprehensions were borrowed from Haskell.

If you feel some deep need to use map, then you will have to approach it like this:

>>> import itertools
>>> list(map(lambda f,a : f(a), *zip(*itertools.product(funcs,args))))
[4, 5, 6, 8, 10, 12, 12, 15, 18]

Which is eminently unreadable and likely slower. List comprehensions win here.

like image 158
juanpa.arrivillaga Avatar answered Dec 08 '22 00:12

juanpa.arrivillaga


If you want to use map(), you could do:

>>> [k for item in map(lambda x: [g(x) for g in listFunc], ListArg) for k in item]
[5, 6, 7, 6, 7, 8, 7, 8, 9]
like image 42
Simeon Visser Avatar answered Dec 07 '22 22:12

Simeon Visser