This article focuses on ** and * Prefix operators,** *and ** operators used before variables.
A star (*): indicates that the received parameters are treated as tuples
Two stars (**): indicates that the received parameters are treated as a dictionary
Simple example.
>>> numbers = [2, 1, 3, 4, 7] >>> more_numbers = [*numbers, 11, 18] >>> print(*more_numbers, sep=', ') 2, 1, 3, 4, 7, 11, 18
Uses.
- Passing arguments to functions using * and **
- Using ** and ** to capture arguments passed to a function
- Use * to accept only keyword arguments
- Capturing items during unpacking using * tuples
- Use * to unwrap iterables into a list/tuple
- Use **To unzip the dictionary to other dictionaries
Example Explanation.
1. When calling a function, * you can use operators to decompress iterable objects into arguments in the function call:
>>> fruits = ['lemon', 'pear', 'watermelon', 'tomato'] >>> print(fruits[0], fruits[1], fruits[2], fruits[3]) lemon pear watermelon tomato >>> print(*fruits) lemon pear watermelon tomato
That print(*fruits) line passes all the items in the fruits list print as separate arguments to the function call without us even knowing how many arguments are in the list.
2.** The ** operator allows us to take a dictionary of key-value pairs and decompress it into keyword arguments in a function call.
>>> date_info = {'year': "2020", 'month': "01", 'day': "01"} >>> filename = "{year}-{month}-{day}.txt".format(**date_info) >>> filename ''
** Unpacking keyword arguments into function calls is not very common. Where I see it most often is when practicing inheritance: super() usually has to contain both * and **.
Both sides *and* ** can be used multiple times in function calls, like in Python 3.5.
>> fruits = ['lemon', 'pear', 'watermelon', 'tomato'] >>> numbers = [2, 1, 3, 4, 7] >>> print(*numbers, *fruits) 2 1 3 4 7 lemon pear watermelon tomato **Multiple uses of similar: >>> date_info = {'year': "2020", 'month': "01", 'day': "01"} >>> track_info = {'artist': "Beethoven", 'title': 'Symphony No 5'} >>> filename = "{year}-{month}-{day}-{artist}-{title}.txt".format( ... **date_info, ... **track_info, ... ) >>> filename '2020-01-01-Beethoven-Symphony No '
3. When defining a function, * you can use the operator to capture an unlimited number of positional arguments supplied to the function. These parameters are captured into a tuple.
from random import randint def roll(*dice): return sum(randint(1, die) for die in dice
4. we can capture any keyword argument that gives the function to the dictionary when defining a function with **:
def tag(tag_name, **attributes): attribute_list = [ f'{name}="{value}"' for name, value in () ] return f"<{tag_name} {' '.join(attribute_list)}>"
5. Positional parameters with keyword-only arguments, to accept keyword-only arguments, you can * place a named parameter after use when defining a function
def get_multiple(*keys, dictionary, default=None): return [ (key, default) for key in keys ] The above function can be used like this: >>> fruits = {'lemon': 'yellow', 'orange': 'orange', 'tomato': 'red'} >>> get_multiple('lemon', 'tomato', 'squash', dictionary=fruits, default='unknown') ['yellow', 'red', 'unknown']
The arguments dictionaryand default are followed by *keys, which means that they can only be specified as keyword arguments. If we try to specify them in position, we get an error message:
>>> fruits = {'lemon': 'yellow', 'orange': 'orange', 'tomato': 'red'} >>> get_multiple('lemon', 'tomato', 'squash', fruits, 'unknown') Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: get_multiple() missing 1 required keyword-only argument: 'dictionary'
6. Keyword-only parameters without positional parameters
The keyword-only parameter feature is cool, but what if you need keyword-only parameters without capturing unlimited positional parameters?
def with_previous(iterable, *, fillvalue=None): """Yield each iterable item along with the item before it.""" previous = fillvalue for item in iterable: yield previous, item previous = item ```
The function accepts an iterable parameter, which can be specified either in position (as the first parameter) or by its name and as an argument to the fillvalue keyword-only parameter. This means we can call with_previous like this:
>>> list(with_previous([2, 1, 3], fillvalue=0)) [(0, 2), (2, 1), (1, 3)] But that's not it.: >>> list(with_previous([2, 1, 3], 0)) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: with_previous() takes 1 positional argument but 2 were given This function takes two arguments,And one of them.fillvalue Must be specified as a keywordarguments。
7. Asterisks in tuple unwrapping
Python 3 also adds a new way to use theoperator in a way that is only compatible with the above-when-defining-a-functionrespond in singing*-when-when-calling-afunctionfunctionally related。
>>> fruits = ['lemon', 'pear', 'watermelon', 'tomato'] >>> first, second, *remaining = fruits >>> remaining ['watermelon', 'tomato'] >>> first, *remaining = fruits >>> remaining ['pear', 'watermelon', 'tomato'] >>> first, *middle, last = fruits >>> middle ['pear', 'watermelon']
8. List text in the asterisk
Python 3.5 introduces a large number of new features with PEP 448. One of the biggest new features is the ability to dump iterable objects into a new list.
Suppose you have a function that takes any sequence and returns a list where that sequence is concatenated with the reverse order of that sequence:
def palindromify(sequence): return list(sequence) + list(reversed(sequence))
The function needs to convert things to lists a couple times to concatenate the lists and return the result. In Python 3.5, we can instead type:
def palindromify(sequence): return [*sequence, *reversed(sequence)]
This code removes some unnecessary list calls, so our code is more efficient and readable.
This is another example:
def rotate_first_item(sequence): return [*sequence[1:], sequence[0]]
This function returns a new list where the first item in the given list (or other sequence) moves to the end of the new list.
This use of the * operator is a great way to join iterable objects of different types together. The * operator applies to any iterable, while using the + operator only applies to a specific sequence with all the same types.
This is not limited to creating lists. We can also dump iterable items into new tuples or collections:
>>> fruits = ['lemon', 'pear', 'watermelon', 'tomato'] >>> (*fruits[1:], fruits[0]) ('pear', 'watermelon', 'tomato', 'lemon') >>> uppercase_fruits = (() for f in fruits) >>> {*fruits, *uppercase_fruits} {'lemon', 'watermelon', 'TOMATO', 'LEMON', 'PEAR', 'WATERMELON', 'tomato', 'pear'}
Note that the last line above takes a list and a generator and dumps them into the new set. Before using it*, there wasn't an easy way to do this in one line of code before. There used to be a way to do it, but it wasn't easy to remember or discover:
>>> set().union(fruits, uppercase_fruits) {'lemon', 'watermelon', 'TOMATO', 'LEMON', 'PEAR', 'WATERMELON', 'tomato', 'pear'}
9. Double asterisks in dictionary text
PEP 448 also** extends functionality by allowing this operator to be used to dump key/value pairs from one dictionary to a new dictionary:
>>> date_info = {'year': "2020", 'month': "01", 'day': "01"} >>> track_info = {'artist': "Beethoven", 'title': 'Symphony No 5'} >>> all_info = {**date_info, **track_info} >>> all_info {'year': '2020', 'month': '01', 'day': '01', 'artist': 'Beethoven', 'title': 'Symphony No 5'}
For example, we can copy the dictionary while adding new values:
>>> date_info = {'year': '2020', 'month': '01', 'day': '7'} >>> event_info = {**date_info, 'group': "Python Meetup"} >>> event_info {'year': '2020', 'month': '01', 'day': '7', 'group': 'Python Meetup'}
or copy/merge dictionaries while overriding specific values:
>>> event_info = {'year': '2020', 'month': '01', 'day': '7', 'group': 'Python Meetup'} >>> new_info = {**event_info, 'day': "14"} >>> new_info {'year': '2020', 'month': '01', 'day': '14', 'group': 'Python Meetup'}
ref: /2018/10/asterisks-in-python-what-they-are-and-how-to-use-them/
summarize
To this point this article on python prefix operator * and ** example of the use of detailed articles on this, more related python * and ** usage content please search my previous articles or continue to browse the following related articles I hope that you will support me more in the future!