0

i got this task today from school to make a function Sum(list): i researched and found out few ways how to make it work with list that consist of int, or list of list of integers, however my function should work also with other types like string, or tuples. Here are some examples of what it should do.

Sum([1,2,3]) returns 6;  Sum([2,[1.5,3],0.5]) returns 7.0;
Sum([[['p'],'yt'],['h',['on']]]) returns 'python'
Sum([[(1,2)],(3,),[(4,5)]])  returns (1, 2, 3, 4, 5);

And on top of that all it should be also able to compute if argument in the function Sum(X) is NOT list. Example:

Sum(5*5) returns 25;

This is what i am working with so far, works fine for first 2 cases, however i cant find a way to modify it to work for other examples. Personaly ive been trying to use isinstance and exceptions

def list_sum(L):
    total = 0  
    for i in L:
        if isinstance(i, list): 
            total += list_sum(i)
        else:
            total += i
    return total

Many thanks for any kind of help

Yondaru
  • 87
  • 7

2 Answers2

1

Use the first non-list value as the initial value for the sum. Let None signify that we did not yet see such value:

def list_sum(L):
    if not isinstance(L, list):
        return L

    total = None
    for i in L:
        i = list_sum(i)

        if total is None:
            total = i
        else:
            total += i
    return total

Also, in this case, using isinstance is the sanest thing to do.


For the really robust case that handles empty lists correctly, make use of a flattening generator:

def list_sum(l):
    def flatten(l):
        for el in l:
            if isinstance(el, list):
                for sub in flatten(el):
                    yield sub
            else:
                yield el

    if isinstance(l, list):
        return sum(flatten(l))
    return l

Note that the builtin sum function works in that case.

Community
  • 1
  • 1
0

Here is a one-liner for doing this with just integers, for future reference:

from itertools import chain as flatten

def nested_sum(l):
    return sum(flatten.from_iterable(l))

itertools.chain is great for flattening nested iterables.

Anorov
  • 1,990
  • 13
  • 19