1

I know how to get the sum of a nested list that only contains numbers but how do i get the sum of a nested list that contains both strings and numbers?

def sum_all_numbers(seq):
    if not seq:
        return 0
    elif isinstance(seq[0], str):
        seq.remove(seq[0])
    elif isinstance(seq[0], list):
        return sum_all_numbers(seq[0]) + sum_all_numbers(seq[1:])
    else:
        return seq[0] + sum_all_numbers(seq[1:])

I wanted to use double recursion to solve this problem but i don't manage to get the isinstance part right.

sum_all_numbers(["a", "b", ["c", 3, 4, [5, "d"], 10], 9])

is the input

Mabest
  • 21
  • 1
  • Note that when you do `seq.remove(seq[0])`, you're actually modifying `seq` and deleting an element!! This is not what your function is supposed to do; it's only supposed to sum the numbers without damaging the list. Other languages have a `const` keyword to guarantee that a function won't damage its arguments; python doesn't, so you have to be extra careful. – Stef Dec 23 '21 at 15:54

2 Answers2

0

you can flatten all the list to a single list and then traverse and filter the list reuslt or while traversing the list filter the values.

using the second method adding code

# your code goes here
def get_sum(array: list):
    sum_ = 0
    for i in array:
        if type(i)==int:
            sum_+= i
        elif type(i) in [list, tuple]:
            sum_+= get_sum(i)
    return sum_


result = get_sum(["a", "b", ["c", 3, 4,(1,2,['a', 'b', [1,2,0]],'a',33), [5, "d"], 10], 9])
print(result)
# output 70
sahasrara62
  • 10,069
  • 3
  • 29
  • 44
  • Why did you replace the OP's `isinstance()` with `type() ==`? See also [What are the differences between `type` and `isinstance`?](https://stackoverflow.com/questions/1549801/what-are-the-differences-between-type-and-isinstance/1549854) – Stef Dec 23 '21 at 15:56
  • in this case `type` is better than `isinstance` in this case – sahasrara62 Dec 23 '21 at 18:39
  • You make it sound like it's just your personal taste ;-) – Stef Dec 23 '21 at 22:15
0

I suggest using:

  • try/except to try adding numbers;
  • isinstance(x, (str, bytes)) to test if x is a string.

This way, you can add any numbers, not just int.

def sum_all_numbers(seq):
    result = 0
    for x in seq:
        try:
            result += x
        except TypeError:
            if not isinstance(x, (str, bytes)):
                result += sum_all_numbers(x)
    return result

print( sum_all_numbers(["a", "b", ["c", 3, 4, [5, "d"], 10], 9]) )
# 31

Note that this version will fail if the nested structure contains something that is not a number, a string, or an iterable:

sum_all_numbers([None, 3, 4])
# TypeError: 'NoneType' object is not iterable

To fix it, we can use a new try/except with iter:

def sum_all_numbers(seq):
    result = 0
    for x in seq:
        try:
            result += x
        except TypeError:
            if not isinstance(x, (str, bytes)):
                try:
                    subseq = iter(x)
                    result += sum_all_numbers(subseq)
                except TypeError:
                    pass
    return result

print( sum_all_numbers(["a", "b", ["c", 3, 4, [None, 12.0], [5, "d"], 10], 9]) )
# 43.0

I suggest reading the python sourcecode of more_itertools.collapse, for more ideas and error-handling to include in this function.

Stef
  • 13,242
  • 2
  • 17
  • 28
  • try and exxcept is a costly operation and to use them twice is bad practice. to check any type of object you can check whether that ojbect is iterable or not ie `object.__iter__` and based on output you can make/take a decision no need to use these try and except heavy operation – sahasrara62 Dec 23 '21 at 19:23
  • @sahasrara62 I disagree with your comment. Some objects are iterable, yet do not implement the `.__iter__` method that you mention. See [In python, how do I determine if an object is iterable?](https://stackoverflow.com/questions/1952464/in-python-how-do-i-determine-if-an-object-is-iterable) for a longer discussion on that matter. – Stef Dec 23 '21 at 22:12