Search code examples
pythonrecursionargs

*args in recursion: TypeError: unsupported operand type(s) for +: 'int' and 'tuple'


I am learning python. trying to use take *args as parameter in a recursion function (for addition of 'n' numbers), but getting error: Below is my code and error:


def add(*n):
  if len(n) == 1:
    return n[0]
  else:
    sum =  n[len(n)-1] + add(n[:-1])
  return sum  


a = add(2,4,6)
print(a)

Error:

Traceback (most recent call last):
  File "/tmp/sessions/9d1de49c52e0e9b9/main.py", line 22, in <module>
    a = add(2,4,6)
  File "/tmp/sessions/9d1de49c52e0e9b9/main.py", line 18, in add
    sum =  n[len(n)-1] + add(n[:-1])
TypeError: unsupported operand type(s) for +: 'int' and 'tuple'

please explain what i am doing wrong


Solution

  • I would propose a simpler setup:

    def add(*n):
        if len(n) == 1:
            return n[0]
        return n[0] + add(*n[1:])    # n[1:] gives the "rest" of a list, i.e. all elements after the first. 
    
    • In a function definition (def add(*n):), the star collects multiple separate arguments into a list.
      e.g. when you call add(2, 4, 6), then n will be a list [2, 4, 6]
    • In a function call (add(*n)) the star spreads a list into multiple separate arguments.
      e.g. when you have n = [2, 4, 6], then calling add(*n) will be as if you had called add(2, 4, 6)

    In order to a list that to a function that collects its arguments, you need to spread it out first.

    Your code did the first thing, but not the second. That's why it doesn't work:

    def add(*n):                            # <-- collecting multiple arguments into a list
      if len(n) == 1:
        return n[0]
      else:
        sum =  n[len(n)-1] + add(n[:-1])    # <-- not spreading list into multiple arguments
      return sum  
    

    FWIW, an even shorter implementation would go like this

    def add(*n):
        return 0 if not n else n[0] + add(*n[1:])