Reputation: 874
I have just started writing lambdas in python these days and I wonder whether there's a good way to avoid chaining map/reduce/filter (which causes confusion when closing parenthesis).
Here's a lambda which chains a few level:
a = [1,2,3,4,5,6]
b = [1,0,0,1,0,1]
reduce(lambda x,y:x+y,map(lambda x:a[x],map(lambda x:x[0],filter(lambda (i,x):x==0,enumerate(b))))) # returns 10,2+3+5 where corresponding elements in array b is 0
I still prefer old-school style of OOP like
x.dosomething().doanotherthing().dofoo().dobar()
which make things easier to read for me. Besides defining these as other function variable which causes intermediate results to be calculated, are there any inline ways (that avoid intermediate results to be calculated). How can I do this?
Upvotes: 0
Views: 210
Reputation: 48067
You may use itertools.compress()
which is specifically made for this kind of filtering. For example:
>>> from itertools import compress
>>> list(compress(a, b))
[1, 4, 6]
But this filters the number corresponding to 1
in b
. So firstly you need to flip the value in b
. Hence your solution will be as:
>>> flipped_b = [not i for i in b]
>>> sum(compress(a, flipped_b))
10
# OR, you may do:
>>> sum(a) - sum(compress(a, b))
10
Upvotes: 4
Reputation: 64318
List comprehensions (and generator expressions) are preferable over map/filter/reduce
. Also, if you need the sum of some elements, use sum()
, not reduce().
In your case, zip
is also useful.
How about this?
sum([ x for x,y in zip(a,b) if y==0 ])
Upvotes: 1
Reputation: 19352
I would say it is better not to use reduce
, filter
and map
, because they reduce readibility of the code. Use simpler functions and list comprehensions instead.
So:
reduce(lambda x,y: x+y, something)
, do
sum(something)
filter(lambda i,x: x==0, enumerate(b))
, do [(i,x) for i,x in enumerate(b) if x==0]
map(lambda x:x[0], something)
, do [x[0] for x in something]
In the end, after some optimizations, the whole thing becomes the much more readable:
sum(a[i] for i,x in enumerate(b) if x==0)
Upvotes: 3