>>> import functools
>>> functools.reduce(lambda acc, val: acc + 1 if val == ' ' else 0, list("test test test"), 0)
0
我只想计算文本中的空格,所以我希望函数返回2
(因为有两个空格)而不是0
。
答案 0 :(得分:1)
表达式:
acc + 1 if val == ' ' else 0
被解析为
(acc + 1) if val == ' ' else 0
所以,每次遇到空间时都会重置累加器。所以应该是:
acc + 1 if val == ' ' else acc
或
acc + (1 if val == ' ' else 0)
甚至只是:
acc + (val == ' ')
但是,当然,str.count()
是去那里的方式。
答案 1 :(得分:1)
调试lambda
的简便方法是使用print() or (original lambda content)
。这是有效的,因为print
总是返回None
,因此Python将始终在or
之后执行该部分。
将其应用于您的案例:
import functools
functools.reduce(lambda acc, val: print(acc, val) or (acc + 1 if val == ' ' else 0), list("test test test"), 0)
打印:
0 t
0 e
0 s
0 t
0
1 t
0 e
0 s
0 t
0
1 t
0 e
0 s
0 t
0
这解释了出现了什么问题:如果不是空格,请不要保留acc
umulator。
有几种方法可以解决这个问题。出于调试原因,我会保留print
,但如果你真的想使用其中任何一个,你可能应该删除它。
如果在算术运算中使用,则可以使用布尔行为类似于整数的事实:
functools.reduce(lambda acc, val: print(acc, val) or (acc + (val == ' ')), list("test test test"), 0)
每当遇到空格时,它会向累加器添加1(True
),否则会增加0(False
)。
或者保留acc
:
functools.reduce(lambda acc, val: print(acc, val) or (acc + 1 if val == ' ' else acc), list("test test test"), 0)
但是,使用reduce
和lambda
计算空格的方法要好得多。例如:
"test test test".count(" ")
也适用于您的列表:
list("test test test").count(" ") # but that's slower
或:
from collections import Counter
cnts = Counter("test test test") # counts all letters
cnts[" "]