user984343
user984343

Reputation: 41

Python - Find the sum of a Nested list

I'm having trouble of this recursive nested lists. The problem I have right now is the code work fine if the list isn't at the end of the list... I can't figure out what should I do to fix this.

def rsum(l):
    # Sum of all num in the list
    print l
    if isinstance(l[0], list):

        if len(l[0]) == 0:
            result = 0 + rsum(l[1:])

        else:
            sum_in_list = rsum(l[0])
            result = sum_in_list + rsum(l[1:])

    elif len(l) == 1:
        result = l[0]

    else:
        result = l[0] + rsum(l[1:])

    return result

So it work fine like this

l = [1, 2, [], 3, [2, 100], 4, [5], [], 2]
print rsum(l)
119

But if i do this

l = [1, 2, [], 3, [2, 100], 4, [5], [], [2]]
IndexError: list index out of range

Any help or suggestion to point me in the right direction would be great

Upvotes: 0

Views: 3323

Answers (4)

dawg
dawg

Reputation: 103734

Another version:

>>> flatten = lambda *n: (e for a in n
...     for e in (flatten(*a) if isinstance(a, (tuple, list)) else (a,)))
>>> l = [1, 2, [], 3, [2, 100], 4, [5], [], 2]
>>> sum(flatten(l))
119

In Python 3, you can recursively use yield from to flatten arbitrary lists:

def flatten(L):
    for item in L:
        try:
            yield from flatten(item)
        except TypeError:
            yield item

>>> l = [1, 2, [], 3, [2, 100], 4, [5], [], 2]
>>> sum(flatten(l))
119

Upvotes: 1

Tom Karzes
Tom Karzes

Reputation: 24052

If you pass it an empty list, it will try to access l[0] and cause the error. But here's a simpler solution:

def rsum(l):
    if isinstance(l, list):
        return sum(rsum(v) for v in l)
    else:
        return l

This should handle all cases.

If you want a really concise version, you can use:

def rsum(l):
    return sum(map(rsum, l)) if isinstance(l, list) else l

Upvotes: 0

Paul Rooney
Paul Rooney

Reputation: 21609

Another take

def rsum(L):
    return sum([rsum(i) for i in L]) if isinstance(L, list) else L

Upvotes: 0

Ian Price
Ian Price

Reputation: 7616

If you call l[0] where there are no items in l, an IndexError will be raised.

Catch it like this -

else:
    try:
        result = l[0] + rsum(l[1:])
    except IndexError:
        result = 0

Or check for number of items in l

else:
    if len(l) > 0: 
        result = l[0] + rsum(l[1:])
    else: 
        result = 0

Upvotes: 1

Related Questions