atsushimemet
atsushimemet

Reputation: 31

What does "TypeError: unsupported operand type(s) for +: 'int' and 'tuple'" mean when using built-in sum function?

I'm struggling to understand TypeError when using built-in sum function.

First, I would appreciate if you could check following function.

def mysum(*args):
    print(sum(args))

Second, I implemented following code.

mysum((1, 2, 3, 4, 5))

So, following error was outputted.

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

Thank you for reading this far. It would be awesome if you could teach me this TypeError meaning.

Upvotes: 2

Views: 3007

Answers (3)

tdelaney
tdelaney

Reputation: 77337

When you define def mysum(*args):, python packs the function arguments into the single iterable "args" parameter. From the help text of sum

sum(iterable, /, start=0)
    Return the sum of a 'start' value (default: 0) plus an iterable of numbers

Sum adds the values from the iterable to a start value that defaults to 0 (an integer). When you called mysum, args iterated a single tuple (1, 2, 3, 4, 5) and python attempted to do 0 + (1, 2, 3, 4, 5). You can add a print to the funciton to get a better idea of what's going on

>>> def mysum(*args):
...     print(repr(args))
...     print(sum(args))
... 
>>> mysum((1, 2, 3, 4, 5))
((1, 2, 3, 4, 5),)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in mysum
TypeError: unsupported operand type(s) for +: 'int' and 'tuple'

You could try a list to get a different view of the same problem

>>> mysum([1, 2, 3, 4, 5])
([1, 2, 3, 4, 5],)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in mysum
TypeError: unsupported operand type(s) for +: 'int' and 'list'

You could unpack the tuple in the call. The function will repack it into the args parameter

>>> mysum(*(1, 2, 3, 4, 5))
(1, 2, 3, 4, 5)
15

And you can even redefine the start value and turn this into concatenation

>>> def mysum(*args):
...     print(repr(args))
...     print(sum(args, start=('a', 'b')))
... 
>>> mysum((1,2,3,4,5))
((1, 2, 3, 4, 5),)
('a', 'b', 1, 2, 3, 4, 5)
>>> 
>>> mysum((1,2,3,4,5),(6, 7, 8, 9, 10))
((1, 2, 3, 4, 5), (6, 7, 8, 9, 10))
('a', 'b', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

Upvotes: 1

Mad Physicist
Mad Physicist

Reputation: 114290

A star with a name in the argument list groups positional arguments into a tuple. That means that calling mysum((1, 2, 3, 4, 5)) creates a tuple for args with a single element, which is the tuple you're passing in. It's equivalent to doing the following within the function:

args = ((1, 2, 3, 4, 5),)

The error occurs because the default initial value for sum is the integer 0. You can't add a tuple to it.

Two simple solutions present themselves. The easiest is probably to call the function with individual arguments:

mysum(1, 2, 3, 4, 5)

If you must pass in a tuple, drop the asterisk in the function definition:

def mysum(args):

Upvotes: 0

wasif
wasif

Reputation: 15478

You don't need to expand the argument with *, sum() itself expects list/tuple:

def mysum(args):
    print(sum(args))

mysum((1, 2, 3, 4, 5))

If you need to specify arguments without the tuple (like mysum(1,2...)):

def mysum(*args):
    print(sum(args))

mysum(1, 2, 3, 4, 5)

Upvotes: 0

Related Questions