- Define the variable-length argument functions:
Functions can take a variable number of arguments. A parameter name that begins with * gathers arguments into a tuple. For example, printall takes any number of arguments and prints them:
def printall(*args):
print(args)
def test_var_args(f_arg, *argv):
print("first normal arg:", f_arg)
for arg in argv:
print("another arg through *argv:", arg)
test_var_args('yasoob', 'python', 'eggs', 'test')
>>>
first normal arg: yasoob
another arg through *argv: python
another arg through *argv: eggs
another arg through *argv: test
>>>def f(a, b, c, d):
print(a, b, c, d, sep = '&')
>>>f(1,2,3,4)
1&2&3&4
>>>f(*[1, 2, 3, 4])
1&2&3&4
## The code below can realize the same function:
def f(*args):
print(*args, sep='&')
So * can be used anywhere the variable/expression/return value is a tuple/list:
m = np.array([[1,2],[3,4]])
np.random.randn(*m.shape)
The complement of gather is scatter. If you have a sequence of values and you want to pass it to a function as multiple arguments, you can use the * operator. For example, divmod takes exactly two arguments; it doesn’t work with a tuple:
>>> t = (7, 3)
>>> divmod(t)
TypeError: divmod expected 2 arguments, got 1
##But if you scatter the tuple, it works:
>>> divmod(*t)
(2, 1)
- For unpacking
# example 1
>>> a, *b, c = range(5)
>>> a
0
>>> c
4
>>> b
[1, 2, 3]
# example 2
>>> ecord = ('ACME', 50, 123.45, (12, 18, 2012))
>>> name, *_1, (*_2, year) = record
>>> print(name)
'ACME'
>>> print(_1)
[50,123.45]
>>> print(_2)
[12,18]
>>> print(year)
# example 3
>>> for a, *b in [(1, 2, 3), (4, 5, 6, 7)]:
>>> print(b)
[2, 3]
[5, 6, 7]
So we can apply this feature in recursive algorithms:
def sum(items):
head, *tail = items
return head + sum(tail) if tail else head
items = [1, 10, 7, 4, 5, 9]
print(sum(items))
Note: * can not be used alone:
Wrong usage:
>>> *a = range(5)
>>> a = *range(5)
>>> print(*range(5))
Correct usage:
>>> *a, = range(5)
[0, 1, 2, 3, 4]
>>> a = *range(5),
(0, 1, 2, 3, 4)
>>> *a,b = range(5)
>>> print(*range(5),)