在Python中将整数列表的子集相乘

3

假设我有一个包含10个整数的列表,我想要将前5个数相乘的结果。是否有一种Pythonic的方法来实现这个?Python似乎在处理列表方面非常出色 :)


请查看此问题 - kgiannakakis
5个回答

9
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

1
为什么不用 reduce(operator.mul, l[:5]) ?? 人们确实喜欢使用 enumerate() - Kenan Banks
是的,我为此进行了编辑,因为你正在发布评论。仍在适应“一切都可分片”的概念。该死的PHP。 - chuckharmston
reduce(operator.mul, itertools.islice(l,5)) 避免复制列表,对于足够大的切片可能很重要。 - John La Rooy

4
有很多种方法。这里介绍一种:
>>> a = range(1,10)
>>> reduce(lambda x,y: x*y, a[:5])
120

2

当有多种方法可以完成某项任务时,我会根据可读性或速度等标准来决定使用哪种代码。下面是一些代码,它表明在速度方面use_loopuse_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_loopuse_reduce看起来同样快,因此我建议使用reduce,因为它短小精悍的代码对大多数Python程序员来说应该很容易读懂。但是,在品味方面,我认为过于武断是不明智的。选择你最喜欢的,只要保持一致即可。
PS. 自Python 3+以来,reduce不再是内置函数,但可以通过functools.reduce访问。

你能否尝试使用itertools.islice(a,n)而不是a[:n]来编写一个程序?当n=50时,两者所需的时间大致相同,但当n更大时,使用itertools.islice(a,n)会更加高效。 - John La Rooy

0

使用 reduce 函数:

reduce(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中执行此操作的方式。


0

这是一个简单的函数,可以实现你想要的功能。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接