Python arbitrary argument lists

When we define a function, we usually provide a specific name for each parameter in a function. However, there is a way to scoop an arbitrary number of argument lists under one parameter name.

The parameter name that scoops the arbitrary argument lists has a different format. It is required that the parameter name has the character ‘*‘ or ‘**‘ in front of the parameter name.

The single ‘*'(asterisk) and the ‘**'(double asterisk) function vary a little bit, they are discussed below.

Parameter with a single ‘*‘(asterisk)

If the parameter holding the arbitrary argument lists has a single ‘*‘ then the arbitrary argument lists is received as a tuple. This simply means, the parameter with the ‘*‘ is treated as a tuple and the arbitrary argument lists as the items.

Consider the code below.

>>> def foo( st , *arg ): #'*arg' holds the arbitrary argument lists
...  print('st=',st)
>>> foo( 'All string' , '1' , '2' , '3' , '4' , '5' )
st= All string

The function foo() has ‘st’ as the first parameter and the second parameter is ‘*arg’. In the foo() calling side, which is ‘foo( “All string”, ‘1’ , ‘2’ , ‘3’ , ‘4’ , ‘5’ )‘, the first argument will be assigned to ‘st’ and the remaining arguments are assigned to ‘*arg’. So, ‘arg’ is a tuple with ‘1 ,2 ,3 ,4 , 5’ as the items.

Note, there is no limit on how many arguments the arbitrary argument lists can consit of.

Unpacking the argument lists

Since the arbitrary argument lists are treated as the items of a tuple, we can access the argument lists in the same way we accessed a tuple object. We can use the ‘for loop’ statement to access the arguments.

Link : Python for loop

>>> def foo(st , *arg):
...  print("st=",st)
...  for val in arg:
...   print(val)
>>> foo( "All string" , '1' , '2' , '3' , '4' , '5' )
st= All string

Easy isn’t?

Parameter with a double ‘**‘(asterisk)

If the parameter has the ‘**‘(double asterisk) then the arbitrary argument lists is received as a dictionary item. Here it is important to note that only those arguments which are passed as keyword arguments is accumulated under the ‘**'(double asterisk) parameter.

The term ‘keyword argument’ refer to those arguments which has the argument name and the value. It is of the form ‘argument_name=argument_value‘. More about keyword arguments can be found in the link provided below.

Link: Python keyword argument

Consider the code example.

>>> def cron( st , heap , **arg):
...  print("st=",st, "\nheap=",heap)
>>> cron( "Candcplusplus" , "Stack",  a='apple' , b='Bam', c='cook' )
st= Candcplusplus
heap= Stack

The arbitrary argument lists:a=’apple’ , b=’Bam’, c=’cook’, is hold by the ‘**arg’ parameter. How to access the argument value is shown below.

Unpacking the keyword argument lists

Like the single ‘*’ parameter we can also use the ‘for loop’ statement to access the arguments of the **(double asterisk) parameter.

>>> def cron(st , heap, **arg):
...  print("st=", st,"\nheap=",heap)
...  for val in arg:
...   print(val,":",arg[val])
>>> cron( "Candcplusplus" , "Stack",  a='apple' , b='Bam', c='cook' )
st= Candcplusplus
heap= Stack
a : apple
b : Bam
c : cook

Some points to note while using the ‘*’ and ‘**’ in arbitrary argument lists.

i)We can use the ‘*'(single asterisk) and the ‘**'(double asterisk) paramter together in a function but note the ‘**’ must always follow the ‘*’ parameter

If we are using the ‘*’ and the ‘**’ parameter in a function, the ‘**’ parameter must always follow the ‘*’ parameter. The order is important!

>>> def fun(sr , *single , **double): #Work fine
...  print( "sr=",sr )
...  for var in single:
...   print(var)
...  for vr in double:
...   print( vr, ":" ,double[vr] )
>>> fun( 'New' , 23, 'heapster', 'Tornado', arg="Arguemnt", Syn="Syntax )
sr= New
arg : Arguemnt
Syn : Syntax
>>> def test(**double , *single): #Error!!!

ii)Only keyword-only argument should follow the ‘*’ parameter and no parameter should follow the ‘**’ parameter including the keyword-only argument

If we want more parameters after the ‘*’ parameter, we may use the keyword-only argument i.e. ‘argument_name=argument_value’. The normal parameter is not allowed.

The ‘**’ parameter is stricter and does not allow any parameters to follow it, including the keyword-only argument.

>>> def f2(**double , arg='1234'): #Error!! keyword-only follows **
>>> def foo( st , *single , mid='Middle argument', **double ): #Work fine
>>> def func( st , *single , arg ): #Error!! a parameter follows * parameter
>>> def flow( **double , arg ): #Error!! a parameter after **
>>> def flip( **double , *single  ): #Error!! * after ** parameter