从所有嵌套列表中累加元素

3

我正在将所有嵌套列表中的元素相加,目前为止我已经有:


for i in range(len(b)) :
    for j in range(len(b[i])):
        total = total + b[i][j]

但是,当嵌套列表中存在整数值时,这种方法将不起作用,例如:
b = [[1,2], [3,4], [5,6], 1]

在这种情况下,我收到了一个错误消息,指出类型为“int”的对象没有长度(len())。 在这种情况下应该怎么做?

这个回答解决了你的问题吗?Python中嵌套列表的求和 - Georgy
5个回答

7

首先,您展示了Python程序员常见的反模式,不要循环索引,而是循环对象本身。例如:

for item in b:
    do_something(item)

不要这样写:

for i in range(len(b)):
    do_something(b[i])

它更清晰、简单和快速。

话虽如此,您遇到的主要问题是其中一个项目不是列表,因此它没有长度。

在这里更好的选择是使用生成器表达式和 itertools.chain.from_iterable() 扁平化列表,然后使用内置函数 sum() 来计算元素的总和。

>>> import collections
>>> import itertools
>>> b = [[1,2], [3,4], [5,6], 1]
>>> list(itertools.chain.from_iterable(item if isinstance(item, collections.Iterable) else [item] for item in b))
[1, 2, 3, 4, 5, 6, 1]
>>> sum(itertools.chain.from_iterable(item if isinstance(item, collections.Iterable) else [item] for item in b))
22

我们需要生成器表达式作为 itertools.chain() 无法处理非可迭代项,因此我们将任何内容放入列表中以解决这个问题。
另一种选择是制作自己的生成器:
def chain_mixed(iterable):
    for item in iterable:
        try:
            for subitem in item:
                yield subitem
        except TypeError:
            yield item

然后,您可以简单地执行以下操作:
sum(chain_mixed(b))

做得很好 - 我会这样写,只是我会使用 item if isinstance(item, collections.Iterable) else [item] - Jon Clements
我是Python世界的新手,所以我只理解了你代码的一半,但是非常感谢你指出我使用的反模式,并向我介绍生成器表达式和列表推导式 :) - Dan
@JonClements 好主意,已更改。 - Gareth Latty
1
@Dan 如果你对列表推导和生成器表达式还不熟悉,我建议你观看我的教程视频 - Gareth Latty
@Lattyware:非常感谢你的视频教程。 - Dan

1
尝试像这样做, 仅当元素是listtuple时使用sum(),否则直接使用数字。
>>> b = [[1,2], [3,4], [5,6], 1]
>>> sum(sum(x) if isinstance(x,(list,tuple)) else x for x in b)
22

优化您的解决方案:

total=0
b = [[1,2], [3,4], [5,6], 1]
for i in range(len(b)) :
    if isinstance(b[i],(list,tuple)):
        for j in range(len(b[i])):
            total += b[i][j]
    else:
        total +=b[i]
print total  #prints 22

但是如果其中一个子列表中还有另一层的列表(例如 b= [[1,2,[1]],[3,4],[5,6],1]),它仍然会失败。 - Joran Beasley
@JoranBeasley,从OP的方法可以看出,他只关注列表的列表,而不是列表的列表的列表。 - Ashwini Chaudhary
@JoranBeasley 这是一个不同的问题。问题并没有要求任意嵌套的列表,而给出的解决方案也没有表明需要这样做。 - Gareth Latty
是的,我知道,我只是指出一下...并没有说它是错误的或其他什么(我给了这个和@Lattyware的解决方案+1)。 - Joran Beasley
@ Joran,谢谢你增加了一个层级。 - Dan
显示剩余2条评论

1
一个基于生成器的解决方案。
>>> b = [[1,2], [3,4], [5,6], 1]
>>> def sum_up(x):
...     for i in x:
...             if isinstance(i, int):
...                     yield i
...             else:
...                     for j in sum_up(i):
...                             yield j
... 
>>> sum(sum_up(b))
22
>>> b = [[1,2], [3,4], [5,6,[3,[6,7]]], 1]
>>> sum(sum_up(b))
38

0

另一种方法

如果列表包含嵌套列表和整数/浮点数,这种方法将起作用。 在这里,我使用了Python内置函数'sum'来添加列表的所有元素。

def add(nested_list):
    temp=[]
    for i in nested_list:
        if isinstance(i,list):
            temp.append(sum(i))
        else:
            temp.append(i)
    print sum(temp)

0
一种方法是这样做
def calc_sum(the_list):
    sum = 0
    for item in the_list:
        if isinstance(item,(list,tuple)):
           sum += calc_sum(item)
        else:
           sum += item
    return sum

虽然不太符合Python的风格...但应该能正常工作


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