我使用reduce函数按如下所示将列表的所有元素相乘。
l = [1,2,3,4,5]
reduce(lambda x,y:x*y,l) #returns 120
[现在,假设我有一个列表l = [1,'apple',2,'apple','apple']
,我想计算“苹果”一词在列表中出现的次数。使用reduce可能吗?
我知道我可以使用l.count('apple')
,但我想知道是否可以使用简化的解决方案。
是,是:
reduce(lambda x,y: x + (y == 'apple'), l, 0)
但是正如您提到的那样,这里不需要使用reduce
。它可能会比其他任何计数方法都慢,并且意图尚不明确。
>>> l
[1, 'apple', 2, 'apple', 'apple']
>>> reduce(lambda x, y: x + (1 if y == 'apple' else 0), l, 0)
3
>>> l = [1,'apple',2,'apple','apple']
>>> reduce(lambda s, i: s+1 if i == "apple" else s, l, 0)
3
您可以将s+1 if i == "apple" else s
部分简化为s + (i == "apple")
,但我认为隐式bool => int转换是神秘的。但是无论如何,使用reduce还是很隐秘的:)。
这最容易使用初始化程序(在调用结束时使用额外的0
来减少),因此您只需要转换第二个参数:
reduce(lambda x, y: x + (1 if y=='apple' else 0), [1,'apple',2,'apple','apple'], 0)
或者您可以将已由地图转换为0和1的内容简化]:>
reduce(lambda x, y: x+y, map(lambda x: 1 if x=='apple' else 0, [1,'apple',2,'apple','apple']))
但是有很多方法可以使之更加自然:
更简单(但不是很有效)的方法是:
len([x for x in [1,'apple',2,'apple','apple'] if x=='apple'])
from operator import mul
from time import clock
n= 10000
li = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
te = clock()
for i in xrange(n):
x = reduce(mul,li)
print clock()-te
te = clock()
for i in xrange(n):
y = reduce(lambda a,b: a*b,li)
print clock()-te
print x==y