在python

时间:2016-11-08 22:11:13

标签: python lambda

我这些天刚刚开始在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()

让我更容易阅读。除了将这些定义为导致计算中间结果的其他函数变量之外,还有任何内联方式(避免计算中间结果)。我怎样才能做到这一点?

3 个答案:

答案 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)

我想最好不要使用reducefiltermap,因为它们会降低代码的可读性。改为使用更简单的函数和列表推导。

所以:

  1. 代替reduce(lambda x,y: x+y, something),做 sum(something)
  2. 而不是filter(lambda i,x: x==0, enumerate(b)),请[(i,x) for i,x in enumerate(b) if x==0]
  3. 而不是map(lambda x:x[0], something),请[x[0] for x in something]
  4. 最后,经过一些优化后,整个事情变得更具可读性:

    sum(a[i] for i,x in enumerate(b) if x==0)
    

答案 2 :(得分:1)

列表推导(和生成器表达式)优于map/filter/reduce。此外,如果您需要某些元素的总和,请使用sum(),而不是reduce()。

在您的情况下,zip也很有用。

这个怎么样?

sum([ x for x,y in zip(a,b) if y==0 ])