Reputation: 31
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
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
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
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