假设我有一个包含10个整数的列表,我想要将前5个数相乘的结果。是否有一种Pythonic的方法来实现这个?Python似乎在处理列表方面非常出色 :)
假设我有一个包含10个整数的列表,我想要将前5个数相乘的结果。是否有一种Pythonic的方法来实现这个?Python似乎在处理列表方面非常出色 :)
import operator
l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print reduce(operator.mul, [v for (k, v,) in enumerate(l) if k < 5])
>> 120
编辑:更好的方法
print reduce(operator.mul, l[:5])
>> 120
reduce(operator.mul, l[:5])
?? 人们确实喜欢使用 enumerate()
。 - Kenan Banksreduce(operator.mul, itertools.islice(l,5))
避免复制列表,对于足够大的切片可能很重要。 - John La Rooy>>> a = range(1,10)
>>> reduce(lambda x,y: x*y, a[:5])
120
当有多种方法可以完成某项任务时,我会根据可读性或速度等标准来决定使用哪种代码。下面是一些代码,它表明在速度方面use_loop
和use_reduce
大致相同(至少对于测试值而言!)
import operator
import itertools
a=range(1,1000)
def use_loop(a,n):
result=1
for num in a[:n]:
result*=num
return result
def use_reduce(a,n):
return reduce(operator.mul, a[:n])
def use_reduce_lambda(a,n):
return reduce(lambda x,y: x*y, a[:n])
def use_islice_loop(a,n):
result=1
for num in itertools.islice(a,n):
result*=num
return result
def use_islice_reduce(a,n):
return reduce(operator.mul, itertools.islice(a,n))
if __name__=='__main__':
n=50
print(use_loop(a,n))
print(use_reduce(a,n))
print(use_reduce_lambda(a,n))
print(use_islice_loop(a,n))
print(use_islice_reduce(a,n))
% python -mtimeit -s"import test" "test.use_loop(test.a,50)"
10000 loops, best of 3: 16.1 usec per loop
% python -mtimeit -s"import test" "test.use_reduce(test.a,50)"
100000 loops, best of 3: 16.3 usec per loop
% python -mtimeit -s"import test" "test.use_islice_loop(test.a,50)"
10000 loops, best of 3: 19.6 usec per loop
% python -mtimeit -s"import test" "test.use_islice_reduce(test.a,50)"
10000 loops, best of 3: 19.2 usec per loop
% python -mtimeit -s"import test" "test.use_reduce_lambda(test.a,50)"
10000 loops, best of 3: 32.1 usec per loop
a
(1000)和n
(50),itertools.islice
似乎并没有提高性能。 use_reduce_lambda
比它的表亲use_reduce
慢得多,后者使用了operator.mul
。需要注意的是,在测试中未包括导入operator
所需的时间。use_loop
和use_reduce
看起来同样快,因此我建议使用reduce
,因为它短小精悍的代码对大多数Python程序员来说应该很容易读懂。但是,在品味方面,我认为过于武断是不明智的。选择你最喜欢的,只要保持一致即可。reduce
不再是内置函数,但可以通过functools.reduce
访问。itertools.islice(a,n)
而不是a[:n]
来编写一个程序?当n=50时,两者所需的时间大致相同,但当n更大时,使用itertools.islice(a,n)
会更加高效。 - John La Rooyreduce(lambda x, y: x*y, mylist[:5])
e.g.,
>>> reduce(lambda x,y:x*y, range(1,5))
24
reduce()
函数将给定的函数(这里是乘法)应用于列表的前两项,从而将它们缩减为一个项。直到列表中只有一个项为止。该项作为结果返回。这种表示法源自函数式编程语言。
result=1
for i in mylist[:5]:
result*=i
e.g,
>>> result=1
>>> for i in range(1,5):
result*=i
>>> result
24
这是在列表中聚合某些函数的最常见方法;它类似于在Java或C中执行此操作的方式。
这是一个简单的函数,可以实现你想要的功能。
def multiply(args):
x= 1
for arg in args:
x*= arg
return x
l = [1, 2, 3, 4, 5, 6, 7, 8, 9]
multiply(l)
>>>362880
multiply(l[:5])
>>>120