如何利用列表理解计算列表的累计积?

问题描述 投票:2回答:5

我正在尝试将下面的循环转换为理解。

问题是给定一个 input_list = [1, 2, 3, 4, 5]返回一个列表,每个元素都是该索引之前的所有元素的倍数,从左到右。

因此,返回列表将是 [1, 2, 6, 24, 120].

我有一个正常的循环(而且还能用)。

l2r = list()
for i in range(lst_len):
    if i == 0:
        l2r.append(lst_num[i])
    else:
        l2r.append(lst_num[i] * l2r[i-1])
python list list-comprehension
5个回答
8
投票

Python 3.8+解决方案。

lst = [1, 2, 3, 4, 5]

curr = 1
out = [(curr:=curr*v) for v in lst]
print(out)

印刷品。

[1, 2, 6, 24, 120]

其他解决方案(含 itertools.accumulate):

from itertools import accumulate

out = [*accumulate(lst, lambda a, b: a*b)]
print(out)

4
投票

好吧,你 可以 这样做(a):

import math

orig = [1, 2, 3, 4, 5]
print([math.prod(orig[:pos]) for pos in range(1, len(orig) + 1)])

这将生成你想要的东西。

[1, 2, 6, 24, 120]

基本上是通过运行一个计数器从 1 列表的大小,在每一点上计算出该位置前所有项的乘积。

pos   values    prod
===  =========  ====
 1   1             1
 2   1,2           2
 3   1,2,3         6
 4   1,2,3,4      24
 5   1,2,3,4,5   120

(a) 只是要记住,这在运行时效率较低,因为它为每一个元素计算完整的乘积(而不是缓存最近获得的乘积)。你可以在使用 使你的代码更紧凑(通常是使用列表理解的原因),用类似于:

def listToListOfProds(orig):
    curr = 1
    newList = []
    for item in orig:
        curr *= item
        newList.append(curr)
    return newList

print(listToListOfProds([1, 2, 3, 4, 5]))

这显然不是一个列表理解,但仍然有其优势,因为它不会在你需要计算的地方弄乱你的代码。

人们似乎经常对Python中的函数解打折扣,只因为这门语言的表现力太强了,而且 允许 列表理解这样的东西,用最少的源代码做很多工作。

但是,除了函数本身之外,这个解决方案也具有单行列表理解的优点,因为它,嗯,只占一行:-)

此外,你可以自由地 变化 函数 (例如,如果你在以后的 Python 版本中找到更好的方法)。 必须改变代码中所有调用它的不同地方。


1
投票

不该 如果一次迭代取决于之前的状态,那么就可以做成一个列表理解!如果目标是一个单行本,那么就可以用@AndrejKesely的解决方案来解决。

如果目标是单行本,那么有很多解决方案,@AndrejKesely的 itertools.accumulate() 是一个优秀的(+1)。 这是我的,滥用 functools.reduce():

from functools import reduce

lst = [1, 2, 3, 4, 5]

print(reduce(lambda x, y: x + [x[-1] * y], lst, [lst.pop(0)]))

但就列表理解而言,@AndrejKesely的基于赋值-表达式的解决方案是错误的(-1)。 这里有一个更自我包含的理解,它不会泄漏到周围的作用域中。

lst = [1, 2, 3, 4, 5]

seq = [a.append(a[-1] * b) or a.pop(0) for a in [[lst.pop(0)]] for b in [*lst, 1]]

print(seq)

但它仍然是错误的做法! 这是基于 类似问题 也因为错误的原因被上票。


0
投票

对于你的列表,可能并不是有意让数字从1开始连续,但对于有意让数字从1开始连续的情况,你可以使用内置的方法。阶乘():

from math import factorial

input_list = [1, 2, 3, 4, 5]
l2r = [factorial(i) for i in input_list]

print(l2r)

产出:

[1, 2, 6, 24, 120]
© www.soinside.com 2019 - 2024. All rights reserved.