SoFunction
Updated on 2024-12-17

Example usage details of prefix operators * and ** in python

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!