x = func(*(xa,) + args)
y = func(*((xc,) + args))
where args is an array and function definition is:
def func(lamb, data):
# statements
I learnt about *args, but I couldn't find the exact difference between these lines.
x = func(*(xa,) + args)
y = func(*((xc,) + args))
where args is an array and function definition is:
def func(lamb, data):
# statements
I learnt about *args, but I couldn't find the exact difference between these lines.
The only difference is the extra set of brackets and one uses xa while the other uses xc, but even that doesn't make much of a difference to the byte code, take a look:
# python 2 needs to use dis.dis(compile("func(*(xa,)+args)","","eval"))
# to get same result, see http://stackoverflow.com/questions/12673074/how-should-i-understand-the-output-of-dis-dis
>>> dis.dis("func(*(xa,)+args)")
1 0 LOAD_NAME 0 (func)
3 LOAD_NAME 1 (xa)
6 BUILD_TUPLE 1
9 LOAD_NAME 2 (args)
12 BINARY_ADD
13 CALL_FUNCTION_VAR 0 (0 positional, 0 keyword pair)
16 RETURN_VALUE
>>> dis.dis("func(*((xc,)+args))")
1 0 LOAD_NAME 0 (func)
3 LOAD_NAME 1 (xc)
6 BUILD_TUPLE 1
9 LOAD_NAME 2 (args)
12 BINARY_ADD
13 CALL_FUNCTION_VAR 0 (0 positional, 0 keyword pair)
16 RETURN_VALUE
This is a simple matter of precedence, the addition takes priority over the * unpacking (CALL_FUNCTION_VAR is the exact bytecode used) so adding brackets doesn't change anything, much like here:
3 * 5 + 1
The multiplication will happen first so adding brackets around it:
(3 * 5) + 1
Doesn't change what is going to happen.
Also note that you don't have to add tuples together when unpacking arguments, you can just as easily do:
func(xa, *args)
to accomplish the same result without having to add tuples together (and this will work when args is something other then a tuple where as your version would raise a TypeError)