In functions, you can define a number of mandatory arguments:

def fun1(arg1, arg2, arg3): 
    return (arg1,arg2,arg3)

which will make the function callable only when the three arguments are given:

fun1(1, 2, 3)

and you can define the arguments as optional, by using default values:

def fun2(arg1='a', arg2='b', arg3='c'):
    return (arg1,arg2,arg3)

so you can call the function in many different ways, like:

fun2(1)              → (1,b,c)
fun2(1, 2)           → (1,2,c)
fun2(arg2=2, arg3=3) → (a,2,3)
...

But you can also use the destructuring syntax to pack arguments up, so you can assign variables using a list or a dict.

Packing a list of arguments

Consider you have a list of values

l = [1,2,3]

You can call the function with the list of values as an argument using the \\* syntax:

fun1(*l)
# Returns: (1,2,3)
fun1(*['w', 't', 'f'])
# Returns: ('w','t','f')

But if you do not provide a list which length matches the number of arguments:

fun1(*['oops'])
# Raises: TypeError: fun1() missing 2 required positional arguments: 'arg2' and 'arg3'

Packing keyword arguments

Now, you can also pack arguments using a dictionary. You can use the ** operator to tell Python to unpack the dict as parameter values:

d = {
  'arg1': 1,
  'arg2': 2,
  'arg3': 3
}
fun1(**d)
# Returns: (1, 2, 3)

when the function only has positional arguments (the ones without default values) you need the dictionary to be contain of all the expected parameters, and have no extra parameter, or you’ll get an error: