0

I have a function with arbitrary number of arguments and need to add those arguments when they are numbers or can be turned to numbers. Example:

def object_sum(*args):
    pass

print(object_sum(3, 'sun', '5', ['5', 'earth'], (5, '5')))
#Would print 23
  • Why isn't it `8`? You can't convert a list or tuple to a number. – Barmar Oct 08 '21 at 20:30
  • @Barmar lol, are you a teacher ? Your question is pedagogically perfect for StackOverflow beginners ! – TheEagle Oct 08 '21 at 20:31
  • 1
    Is `['5', 'earth']` not a number or do you want to iterate that sequence and get its numbers? How many levels of nesting? Is there a list in a list in a list? – tdelaney Oct 08 '21 at 20:32
  • Loop over the arguments. Try to convert it to a number. Use `try/except` to catch if it fails. If it's iterable, call the function recursively with that as the arguments. – Barmar Oct 08 '21 at 20:33
  • @Programmer - Its an important question. Should sequences be iterated? Which sequences? It can end up infinite. A sequence that iterates iterable sequences forever.. `str` is that way. – tdelaney Oct 08 '21 at 20:35

2 Answers2

1

Assuming you want to catch the nested integers, do:

from collections.abc import Iterable


def object_sum(*args):
    def flatten(l):
        # https://stackoverflow.com/a/2158532/4001592
        for el in l:
            if isinstance(el, Iterable) and not isinstance(el, (str, bytes)):
                yield from flatten(el)
            else:
                try:
                    yield int(el)
                except ValueError:
                    yield 0

    return sum(flatten(args))


print(object_sum(3, 'sun', '5', ['5', 'earth'], (5, '5')))

Output

23
Dani Mesejo
  • 61,499
  • 6
  • 49
  • 76
0

Test if the argument is a list or similar, if yes, recurse into it, if not, try to convert it to an integer:

def object_sum(*args):
    result = 0
    for arg in args:
        arg_type = type(arg)
        if arg_type in (list, tuple, set, range):
            result += object_sum(*arg) # The asterisk is important - without it, the recursively called function would again call itself, and we'd get a RecursionError
        else:
            try:
                result += int(arg) # Try to convert to int
            except ValueError:
                pass # arg is not convertable, skip it
    return result

print(object_sum(3, 'sun', '5', ['5', 'earth'], (5, '5')))

Output:

23
TheEagle
  • 5,808
  • 3
  • 11
  • 39