Unpacking Function Argument

unpacking function argument

You are looking for the *args argument syntax:

>>> def foo(bar, baz, spam):
... print bar, baz, spam
...
>>> arguments = [1, 2, 3]
>>> foo(*arguments)
1, 2, 3

When passing arguments to a callable, any expression preceded by a * asterix, is interpreted as a sequence of positional arguments, and expanded to be passed on as separate arguments to the called object (function, method, etc.).

For your example that would be:

func1(*func2(...))

There is a keyword equivalent using ** double asterixes (takes a mapping), and you can use the same syntax in function signatures too.

See the documentation on call expressions, and for the function signature mirror syntax, the documentation on function definitions.

How to Pass a unpack iterator as an Argument to a Function?

f(*(1, 2)) does have context! The context is the list (and dictionary) of function arguments itself. In essence, in a function call f(...) the stuff between the parentheses can be seen as a hybrid between a tuple and a dictionary literal (only using x=4 instead of 'x': 4), which then gets passed to the function:

>>> def f(*args, **kwargs):
... print(args, kwargs)
>>> l = [10, 11]; d = {'a': 12, 'b': 13}
>>> f(1, *l, 2, 3, x=4, y=5, **d, z=6)
(1, 10, 11, 2, 3) {'x': 4, 'y': 5, 'a': 12, 'b': 13, 'z': 6}

Viewed like this it makes perfect sense that you can unpack sequences and dictionaries into this context.

Python: can I unpack arguments without calling a function?

Note: this approach is dangerous. You should not (in most circumstances) muddle with locals() or globals(). However, what you want can be done, kind of:

>>> kwargs = {'this': 7, 'that': 'butterfly'}
>>>
>>> locals().update(kwargs)
>>> this
7
>>> that
'butterfly'

It still calls a function (the update on locals()) but it does give you names in your local namespace.

Python - value unpacking order in method parameters

With *(23,), you are unpacking the values in the tuple (23,) as positional arguments, following the positional arguments that are already defined, namely 3 for a and 7 for b, so 23 would be assigned to parameter c, which is why fun(3, 7, d=10, *(23,)) works, but in fun(3, 7, c=10, *(23,)) you are also assigning to value 10 to c as a keyword argument, so it is considered a conflict as c cannot be assigned with both 23 and 10.

Note that while legal, it is discouraged by some to unpack iterable arguments after keyword arguments, as discussed here, although the syntax is ultimately ruled to stay.

How to unpack parameters in Python?

Parameter unpacking was removed in Python 3 because it was confusing. In Python 2 you can do

def foo(arg, (arg2, arg3)):
pass

foo( 32, [ 44, 55 ] )

The equivalent code in Python 3 would be either

def foo(arg, arg2, arg3):
pass

foo( 32, *[ 44, 55 ] )

or

def foo(arg, args):
arg2, arg3 = args

foo( 32, [ 44, 55 ] )

Unpacking arguments: how to stop a list from turning to a nested list

def biggest_gap(*args):

means that args will be a list (well, technically a tuple) of all arguments you gave to the biggest_gap function.

biggest_gap(other_func(3))

will give a list to the biggest_gap function. That's one argument.

So what you get is "a tuple of (a list)".

What you meant to do was giving a multiple individual arguments, by "splatting" the list returned from other_func:

biggest_gap(*other_func(3))

The difference the * makes is

biggest_gap([322, 32, 12])    # without * - biggest_gap receives 1 argument
biggest_gap(*[322, 32, 12]) # with * - biggest_gap receives 3 arguments
biggest_gap(322, 32, 12) # hard-coded equivalent

See https://docs.python.org/3/tutorial/controlflow.html#unpacking-argument-lists



Related Topics



Leave a reply



Submit