An asterisk in Python besides multiplying x*y ( help('*') ) and raising to a power x**y ( help('**') ) † is used to denote zero or more .
For example, in the description of the parameters of the function:
def f(*args): print(args)
* means that the function takes zero or more arguments that are available inside the function as an args tuple:
>>> f(1,'a') (1, 'a')
Named parameters use two asterisks :
def g(a, b, *args, name='default', **kwargs): print(a, b, args, name, kwargs)
here g() takes two required arguments and an arbitrary (zero or more) number of other arguments:
>>> g(1, b=2, c=3) 1 2 () default {'c': 3}
kwargs is a dictionary of additional arguments passed by name ( c in this case). And args is an empty tuple () , since no additional positional arguments were passed.
After * all parameters must be passed by name, for example :
def min_item(items, *, key=lambda x: x): ...
When called, if specified, the key must be specified by name: min([1,2,-3], key=abs) .
Accepting an arbitrary number of arguments can be useful when creating wrapper functions:
def my_print(*args, **kwargs): flush = kwargs.pop('flush', True) # flush unless overriden print(*args, flush=flush, **kwargs)
With multiple inheritance **kwargs helps to implement the parameter compatibility requirement for base class methods, since kwargs allows you to pass arbitrary named arguments.
It can be seen that the asterisk can also be used when calling a function :
L = [1, 2, 3] s = "abc" print(*L, *s) # iterable unpacking: print(1, 2, 3, 'a', 'b', 'c') # -> 1 2 3 abc
arbitrary collections (iterable in general) L , s unpacked and each of their elements is passed as a separate argument to the called function ( print() ).
Can be used with explicit assignment:
>>> first, *middle, last = L >>> first, middle, last (1, [2], 3)
in this case, the first and last arguments from list L unpacked into explicitly given names ( first , last ), and the remainder zero or more elements as a list are placed in the middle .
The asterisk can also be used when defining lists, tuples, sets and dictionaries in the source code using the appropriate syntax ( tuple, list, set , and dictionary displays ):
>>> *range(4), 4 (0, 1, 2, 3, 4) >>> [*range(4), 4] [0, 1, 2, 3, 4] >>> {*range(4), 4} {0, 1, 2, 3, 4} >>> {'x': 1, **{'y': 2}} # dictionary unpacking inside dictionary display {'x': 1, 'y': 2}
Subtle point: a comma in Python creates a tuple — brackets are needed only for an empty tuple () . Therefore, the first line is equivalent to: (*range(4), 4) .
Just like when calling functions, the asterisk unpacks the collection here and acts as if each element was transferred separately to the appropriate constructors.
Thus, you can add two dictionaries or arbitrary mappings ( Mapping ):
>>> a = {'a': 1, 'b': 2} >>> b = {'a': 3, 'c': 0} >>> {**a, **b} {'a': 3, 'b': 2, 'c': 0} >>> {**b, **a} {'a': 1, 'c': 0, 'b': 2}
If there are duplicate keys, later values win as usual : {'a': 1, 'a': 3} == {'a': 3} .
Knowing what an asterisk makes is useful to explain how zip(*matrix) transposes a square matrix or how to bypass an iterator exactly n elements at a time: zip(*[iterator]*n) .
In addition to the specified values, an asterisk may be present in the file name for creating a wildcard, for example :
from pathlib import Path print(*Path().glob('*.py')) print(*Path().glob('**/*.py'))
The first print() prints all (zero or more) file names in the current directory with the .py extension. Similar ( *.py ) syntax is popular because it is used on the command line (shell).
The second print() with two asterisks ( '**/*.py' ) displays the names of Python files in the entire directory tree (including the subdirectories).
In regular expressions * means repeating zero or more times:
import re if re.fullmatch(r'x*', text): print('текст пустой или содержит только `x`')
† multiplication of natural numbers n*m can be considered as a repetition of addition (zero or more) times. Similarly, raising to the power of n**m can be considered as a repetition of multiplication:
2 * 3 == 2 + 2 + 2 2 ** 3 == 2 * 2 * 2 [2] * 3 == [2, 2, 2]
**(double star) and*(star) do for parameters? - jfs