12

I try to sum a list of nested elements

e.g, numbers=[1,3,5,6,[7,8]] should produce sum=30

I wrote the following code :

def nested_sum(L):
    sum=0
    for i in range(len(L)):
       if (len(L[i])>1):
          sum=sum+nested_sum(L[i])
       else:
          sum=sum+L[i]
    return sum

The above code gives following error:

object of type 'int' has no len()

I also tried len([L[i]]), still not working.

Anyone can help? It is Python 3.3

Arkistarvh Kltzuonstev
  • 6,824
  • 7
  • 26
  • 56
Jin
  • 1,203
  • 4
  • 20
  • 44
  • 2
    Try one of the numerous [flatten functions](http://stackoverflow.com/questions/2158395/flatten-an-irregular-list-of-lists-in-python) posted here so far, and simply `sum(flatten(L))` – georg Feb 17 '13 at 09:12
  • For Python, if I use recursive call, do I need to worry about taking too much time as the stack goes? I know for this problem, I probably won't worry about this – Jin Feb 19 '13 at 15:01
  • @Jin It's probably a little early for this, but if you want to reduce memory consumption, use a [generator](http://wiki.python.org/moin/Generators) instead. – 2rs2ts Jul 09 '13 at 22:56

16 Answers16

33

You need to use isinstance to check whether an element is a list or not. Also, you might want to iterate over the actual list, to make things simpler.

def nested_sum(L):
    total = 0  # don't use `sum` as a variable name
    for i in L:
        if isinstance(i, list):  # checks if `i` is a list
            total += nested_sum(i)
        else:
            total += i
    return total
Volatility
  • 31,232
  • 10
  • 80
  • 89
7

One alternative solution with list comprehension:

>>> sum( sum(x) if isinstance(x, list) else x for x in L )
30

Edit: And for lists with more than two levels(thx @Volatility):

def nested_sum(L):
    return sum( nested_sum(x) if isinstance(x, list) else x for x in L )
7

It is generally considered more pythonic to duck type, rather than explicit type checking. Something like this will take any iterable, not just lists:

def nested_sum(a) :
    total = 0
    for item in a :
        try:
            total += item
        except TypeError:
            total += nested_sum(item)
    return total
Jaime
  • 65,696
  • 17
  • 124
  • 159
5

I would sum the flattened list:

def flatten(L):
    '''Flattens nested lists or tuples with non-string items'''
    for item in L:
        try:
            for i in flatten(item):
                yield i
        except TypeError:
            yield item


>>> sum(flatten([1,3,5,6,[7,8]]))
30
dansalmo
  • 11,506
  • 5
  • 58
  • 53
  • Also works with nested tuples and sets. ```sum(flatten([(1, 2), [3, {4, 5}]]))```. Excellent! – MarkS May 14 '18 at 13:19
3

A quick recursion that uses a lambda to handle the nested lists:

rec = lambda x: sum(map(rec, x)) if isinstance(x, list) else x

rec, applied on a list, will return the sum (recursively), on a value, return the value.

result = rec(a)
njzk2
  • 38,969
  • 7
  • 69
  • 107
1

An example using filter and map and recursion:

def islist(x): 
    return isinstance(x, list)

def notlist(x): 
    return not isinstance(x, list)

def nested_sum(seq):
    return sum(filter(notlist, seq)) + map(nested_sum, filter(islist, seq))

And here is an example using reduce and recursion

from functools import reduce


def nested_sum(seq):
    return reduce(lambda a,b: a+(nested_sum(b) if isinstance(b, list) else b), seq)

An example using plain old recursion:

def nested_sum(seq):
    if isinstance(seq[0], list):
        head = nested_sum(seq[0])
    else:
        head = seq[0]
    return head + nested_sum(seq[1:])

An example using simulated recursion:

def nested_sum(seq):
    stack = []
    stack.append(seq)
    result = 0
    while stack:
        item = stack.pop()
        if isinstance(item, list):
            for e in item:
                stack.append(e)
        else:
            result += item
    return result

Adjustment for handling self-referential lists is left as an exercise for the reader.

Rob Bricheno
  • 4,467
  • 15
  • 29
Broseph
  • 1,655
  • 1
  • 18
  • 38
1

This code also works.

def add_all(t):
    total = 0
    for i in t:
        if type(i) == list: # check whether i is list or not
            total = total + add_all(i)
        else:
            total += i
    return total
yashraj
  • 31
  • 4
1
 def sum_nest_lst(lst):
         t=0
         for l in lst:
             if(type(l)==int):
                 t=t+l
             if(type(l)==list):
                 t=t+sum(l)
         print(t)
ppwater
  • 2,315
  • 4
  • 15
  • 29
0
def nnl(nl): # non nested list function

    nn = []

    for x in nl:
        if type(x) == type(5):
            nn.append(x)

        if type(x) == type([]):
            n = nnl(x)

        for y in n:
            nn.append(y)

     return sum(nn)


 print(nnl([[9, 4, 5], [3, 8,[5]], 6])) # output:[9,4,5,3,8,5,6]

 a = sum(nnl([[9, 4, 5], [3, 8,[5]], 6]))
 print (a) # output: 40
  • This works fine for any nested list. To get the expected output you need to go through two phases: 1. Transform the nested list in a normal list 2. Sum up the normal list – Alessandro Anderson Aug 24 '18 at 14:36
0

A simple solution would be to use nested loops.

def nested_sum(t):

    sum=0
    for i in t:
        if isinstance(i, list):
            for j in i:
                sum +=j
        else:
            sum += i        
    return sum
chb
  • 1,727
  • 7
  • 25
  • 47
0
L = [1, 2, 3, [4, 5, 6], 5, [7, 8, 9]]
total = 0 # assign any var 
for a in L: # assign index and start to iterate using if else
    if (isinstance(a, list)): # since its a list you are basically repeating the prev step
        for b in a:
            total += b
    else:
        total += a
print(total)
Eric Jin
  • 3,836
  • 4
  • 19
  • 45
0
def list_sum(L):
    return sum(list_sum(x) if isinstance(x, list) else x for x in L)
Anil Kumar
  • 525
  • 6
  • 27
0

at first you should determine the type of the members of the list whether they are list or not before you sum the members .

def nested_sum(x):
sum = 0
for i in range(len(x)):
    if type(x[i]) == list:
        sum += nested_sum(x[i])
    else:
        sum+=x[i]
return sum
Farzin347
  • 1
  • 2
0

This error shows up because 'L' is a integer Perhaps change it to some other data type.

-1
def nested_sum(lists):
total = 0
for lst in lists:
    s = sum(lst)
    total += s
return total
Sumi
  • 1
  • While this code may answer the question, providing some additional context regarding how and why it solves the problem would improve the answer's long-term value. – greg-449 Feb 29 '20 at 10:17
  • Does not answer the original question where list elements can be an `int` or a `list`: "`numbers=[1,3,5,6,[7,8]]`". Cannot apply `sum` on an int. – Gino Mempin Feb 18 '21 at 00:04
-2
    #nested sum

    l = [[1, 2], [3,5], [6,2], [4, 5, 6,9]] 

    def nested_sum(lst):

       sum = 0

       for i in lst:
          for j in i:
             sum = sum + j
       
       print(sum)
    
   
nested_sum(l) 
bguiz
  • 27,371
  • 47
  • 154
  • 243
  • Does not answer the original question where list elements can be an `int` or a `list`: "`numbers=[1,3,5,6,[7,8]]`". Also, don't use `sum` as a variable name. – Gino Mempin Feb 17 '21 at 23:59
  • It works though for me and also for number = [1,3,5,6, [7,8]] – Tausif Khan Feb 19 '21 at 00:08
  • 1
    [No, it doesn't work](https://i.stack.imgur.com/6Z3Es.png) for `[1,3,5,6, [7,8]]`. Because your inner loop does not work if the list element is a plain int, you cannot iterate over an int. – Gino Mempin Feb 19 '21 at 00:12