我这些天刚刚开始在python中编写lambdas,我想知道是否有一种避免链接map / reduce / filter的好方法(这会在关闭括号时引起混淆)。
这是一个连锁几级的lambda:
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
我仍然喜欢老式的OOP,如
x.dosomething().doanotherthing().dofoo().dobar()
让我更容易阅读。除了将这些定义为导致计算中间结果的其他函数变量之外,还有任何内联方式(避免计算中间结果)。我怎样才能做到这一点?
答案 0 :(得分:4)
您可以使用专为此类过滤而制作的itertools.compress()
。例如:
>>> from itertools import compress
>>> list(compress(a, b))
[1, 4, 6]
但是这会过滤1
中与b
对应的数字。首先,您需要翻转b
中的值。因此,您的解决方案将如下:
>>> 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
答案 1 :(得分:3)
我想最好不要使用reduce
,filter
和map
,因为它们会降低代码的可读性。改为使用更简单的函数和列表推导。
所以:
reduce(lambda x,y: x+y, something)
,做
sum(something)
filter(lambda i,x: x==0, enumerate(b))
,请[(i,x) for i,x in enumerate(b) if x==0]
map(lambda x:x[0], something)
,请[x[0] for x in something]
最后,经过一些优化后,整个事情变得更具可读性:
sum(a[i] for i,x in enumerate(b) if x==0)
答案 2 :(得分:1)