23

I'd like to learn how to pass an arbitrary number of args in a python function, so I wrote a simple sum function in a recursive way as follows:

def mySum(*args):
  if len(args) == 1:
    return args[0]
  else:
    return args[-1] + mySum(args[:-1])

but when I tested mySum(3, 4), I got this error:

TypeError: unsupported operand type(s) for +: 'int' and 'tuple'

Does anyone have an idea about this and gimme some clue to correct it?

0

6 Answers 6

15

This line:

return args[-1] + mySum(args[:-1])

args[:-1] returns a slice of the arguments tuple. I assume your goal is to recursively call your function using that slice of the arguments. Unfortunately, your current code simply calls your function using a single object - the slice itself.

What you want to do instead is to call with those args unrolled.

return args[-1] + mySum(*args[:-1])
                        ^---- note the asterisk

This technique is called "unpacking argument lists," and the asterisk is sometimes (informally) called the "splat" operator.

Sign up to request clarification or add additional context in comments.

2 Comments

splat (the term) isn't as commonly used as I think it ought to be. Some call it the "star" operator, others just the "unpacking" operator... I suppose it has many names.
@mgilson: too bad itertools.starmap wasn't named itertools.splatmap, :-)
2

If you don't want to do it recursively:

def mySum(*args):
    sum = 0
    for i in args:
        sum = sum + i
    return sum

Comments

1

args[:-1] is a tuple, so the nested call is actually mySum((4,)), and the nested return of args[0] returns a tuple. So you end up with the last line being reduced to return 3 + (4,). To fix this you need to expand the tuple when calling mySum by changing the last line to return args[-1] + mySum(*args[:-1]).

Comments

1

In your code, args[:-1] is a tuple, so mySum(args[:-1]) is being called with the args being a tuple containing another tuple as the first argument. You want to call the function mySum with args[:-1] expanded to the arguments however, which you can do with

mySum(*args[:-1])

Comments

1

The arbitrary arguments are passed as tuple (with one asterisk*) to the function, (you can change it to a list as shown in the code) and calculate the sum of its elements, by coding yourself using a for loop; if don't want to use the sum() method of python.

def summing(*arg):
    li = list(*arg)
    x = 0
    for i in range((len(li)-1)):
        x = li[i]+x

    return x

#creating a list and pass it as arbitrary argument to the function
#to colculate the sum of it's elements

li = [4, 5 ,3, 24, 6, 67, 1]
print summing(li)

Comments

0

Option1:

def mySum(*args):
    return sum(args)

mySum(1,2,3) # 6
mySum(1,2) # 3

Option 2:

mySum2 = lambda *args: sum(args)
mySum2(1,2,3) # 6
mySum2(1,2) # 3

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.