Reputation: 2729
I was reading an online document explaining unpacking (*args
and **kwargs
). Getting confused by the following two asserts, not sure why the second function is invalid. Could anyone help me to understand the reason?
def f(x, y, z):
return [x, y, z]
t = (3,)
d = {"z": 4}
assert f(2, *t, **d) == [2, 3, 4]
assert f(x=2, *t, **d) == [2, 3, 4] # TypeError: f() got multiple values for argument 'x'
Reference https://caisbalderas.com/blog/python-function-unpacking-args-and-kwargs/
Note: This question differs from TypeError: got multiple values for argument because it requires additional knowledge of how argument unpacking works in Python.
Upvotes: 0
Views: 141
Reputation: 36608
You are trying to place a positional argument after a keyword argument. The actual error message is confusing. I am honestly surprised placing tuple unpacking after a keyword is allowed.
It is the similar to doing:
f(x=2, 3, 4)
Which raises a SyntaxError
.
I believe the difference is that the tuple unpacking is handled first and shifts keyword arguments to the right. So effectively, you have this equivalency:
f(x=2, *t, **d)
is that same as
f(*t, x=2, **d)
Which is why you are getting TypeError: f() got multiple values for argument 'x'
Upvotes: 5