累加列表中所有包含整数的元素的总和

3
我想通过itertool的累加函数获取每个列表中所有数字的总和: 这是代码:
from itertools import *
import operator

list_numbers = [[45,43,56,67],[41,423,526,627,897],[545,453,656,667]]

Iterable_list = iter(list_numbers)

while(True):
    try:
        print(list(accumulate(next(Iterable_list),operator.add))[-1])
    except StopIteration as ex:
        print(ex)
        break

以上工作正常。

如果我尝试取出每个列表中的最大值:

while(True):
    try:
        print(list(accumulate(next(Iterable_list),func=max))[-1])
    except StopIteration as ex:
        print(ex)
        break

这也很有效。

我的理解是,如果我使用 func = sum,它将对每个列表执行求和,就像我尝试下面的代码一样,但是它会提示错误消息:

'int' object is not iterable


while(True):
    try:
        print(list(accumulate(next(Iterable_list),func=sum))[-1])
    except StopIteration as ex:
        print(ex)
        break

为什么它不起作用,以及我们在哪些场景下可以使用func = sum


1
为什么不使用以下代码:print([max(l) for l in list_numbers])print([sum(l) for l in list_numbers]) - Eli Harold
1
是的,accumulate 在这里似乎有些过度了。for x in list_numbers: print(sum(x)) - chepner
1
真的。可以用这种方式实现!甚至,我的问题已经通过第一个代码片段(operator.add)得到解决。我正在尝试学习累加函数。 - backbencher
1
请查看 https://docs.python.org/3/library/itertools.html#itertools.accumulate 中的“大致等效于”部分。注意调用传递函数的那一行,并注意调用的方式。 - adang1345
2个回答

0

如果你使用一个lambda函数来探索func将接收到的输入,你可以更好地理解itertools.accumulate的行为。

首先,让我们使用lambda x: print(x)代替sum,打印出这些值:

TypeError: <lambda>() takes 1 positional argument but 2 were given

好的,所以func将接收两个值。让我们尝试一下lambda x, y: print(x, y)

45 43
None 56
None 67
None
41 423
None 526
None 627
None 897
None
545 453
None 656
None 667
None

为什么我们看到了“None”?因为“print()”没有返回任何值,所以返回了一个“None”。
这意味着“func”应该从迭代器(L1和L2)接收两个值,对这两个值进行操作并返回一个单独的值C。然后,使用相同的操作在前一个结果(C)上与迭代器中的下一个值(L3)进行操作。

为什么sum()会失败?

嗯,因为它期望一个单一的参数,即可迭代对象,并且可以选择接受第二个参数(start)。现在,itertools.accumulate 传递了两个值,Python 假定您正在尝试使用 sum(L1, start=L2),但是 L1 不是可迭代的,因为它只是一个数字... TypeError: 'int' object is not iterable

在哪种情况下可以使用 func=sum

sum()可以在接收两个值并返回一个单一值时帮助我们,这是可能的(sum(iterable, start=start))。现在,考虑到sum的输出将作为下一个可迭代对象中使用sum的第一个输入,类似于:sum(sum(L1, start=L2), start=L3)等等。这意味着sum(L1, start=L2)应该返回一个可迭代对象,以便我们能够使用sum。很难找到这方面的例子,这意味着在使用itertools.accumulatesum可能不是任何特定情况的最佳选项,但这并不意味着sum本身没有用处。


1
太棒了!感谢您如此迅速地回复!sum()函数的定义与我想象中的不同,它需要一个迭代器作为第一个输入。当我像下面这样使用lambda的普通加法时就可以工作:while(True): try: print(list((accumulate(next(Iterable_list),func=lambda x,y: x + y)))[-1]) except StopIteration as ex: print(ex) break - backbencher

-1

可以使用Zip()或map()方法或使用numpy来完成此操作。

使用zip():

def nested_sum(lst):
      
 return [sum(i) for i in zip(*lst)]
      
lst = [[2, 4, 6], [2, 2, 1], [1, 2, 3]] # A Sample List
print(nested_sum(lst))

#Output
[12,5,6]

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