1. 程式人生 > 程式設計 >python中字首運算子 *和 **的用法示例詳解

python中字首運算子 *和 **的用法示例詳解

這篇主要探討 ** 和 * 字首運算子,**在變數之前使用的*and **運算子.

一個星(*):表示接收的引數作為元組來處理

兩個星(**):表示接收的引數作為字典來處理

簡單示例:

>>> numbers = [2,1,3,4,7]
>>> more_numbers = [*numbers,11,18]
>>> print(*more_numbers,sep=',')
2,7,18

用途:

  • 使用 * 和 ** 將引數傳遞給函式
  • 使用**和**捕獲傳遞給函式的引數
  • 使用*只接受關鍵字引數
  • 使用*元組拆包過程中捕獲專案
  • 使用*解包iterables到一個列表/元組
  • 使用**要解壓縮詞典到其他字典

例子解釋:

1.呼叫函式時,*可以使用運算子將​​可迭代物件解壓縮為函式呼叫中的引數:

>>> fruits = ['lemon','pear','watermelon','tomato']
>>> print(fruits[0],fruits[1],fruits[2],fruits[3])
lemon pear watermelon tomato
>>> print(*fruits)
lemon pear watermelon tomato

該print(*fruits)行將fruits列表中的所有專案print作為單獨的引數傳遞到函式呼叫中,而我們甚至不需要知道列表中有多少個引數。

2.** 運算子允許我們採取鍵值對的字典,並把它解壓到函式呼叫中的關鍵字引數。

>>> date_info = {'year': "2020",'month': "01",'day': "01"}
>>> filename = "{year}-{month}-{day}.txt".format(**date_info)
>>> filename
'2020-01-01.txt'

** 將關鍵字引數解包到函式呼叫中並不是很常見。我最常看到的地方是練習繼承時:super()通常要同時包含*和**。

雙方*並 **可以在函式呼叫中多次使用,像Python 3.5的。

>> fruits = ['lemon','tomato']
>>> numbers = [2,7]
>>> print(*numbers,*fruits)
2 1 3 4 7 lemon pear watermelon tomato
**多次使用類似:

>>> date_info = {'year': "2020",'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 5.txt'

3.定義函式時,*可以使用運算子捕獲為函式提供的無限數量的位置引數。這些引數被捕獲到一個元組中。

from random import randint

def roll(*dice):
  return sum(randint(1,die) for die in dice

4.我們可以用**定義一個函式時,捕捉給予功能到字典中的任何關鍵字引數:

def tag(tag_name,**attributes):
  attribute_list = [
    f'{name}="{value}"'
    for name,value in attributes.items()
  ]
  return f"<{tag_name} {' '.join(attribute_list)}>"

5.帶有僅關鍵字引數的位置引數,要接受僅關鍵字的引數,可以*在定義函式時在使用後放置命名引數

def get_multiple(*keys,dictionary,default=None):
  return [
    dictionary.get(key,default)
    for key in keys
  ]
上面的函式可以這樣使用:

>>> fruits = {'lemon': 'yellow','orange': 'orange','tomato': 'red'}
>>> get_multiple('lemon','tomato','squash',dictionary=fruits,default='unknown')
['yellow','red','unknown']

引數dictionaryand default在其後*keys,這意味著只能將它們指定為關鍵字引數。如果我們嘗試在位置上指定它們,則會收到錯誤訊息:

>>> fruits = {'lemon': 'yellow',fruits,'unknown')
Traceback (most recent call last):
 File "<stdin>",line 1,in <module>
TypeError: get_multiple() missing 1 required keyword-only argument: 'dictionary'

6.不帶位置引數的僅關鍵字引數
僅關鍵字引數的功能很酷,但是如果您需要僅關鍵字引數而不捕獲無限的位置引數怎麼辦?

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
  ```

該函式接受一個iterable引數,該引數可以在位置上指定(作為第一個引數),也可以通過其名稱和作為fillvalue僅關鍵字引數的引數來指定。這意味著我們可以這樣呼叫with_previous:

>>> list(with_previous([2,3],fillvalue=0))
[(0,2),(2,1),(1,3)]
但不是這樣的:
>>> list(with_previous([2,0))
Traceback (most recent call last):
 File "<stdin>",in <module>
TypeError: with_previous() takes 1 positional argument but 2 were given
此函式接受兩個引數,並且其中一個fillvalue 必須指定為關鍵字arguments。

7.元組拆包中的星號

Python 3還添加了一種新的使用運算子的方式,該方式僅與上面的-when-defining-a-function和*-when-when-calling-afunction功能有關。

>>> fruits = ['lemon','tomato']
>>> first,second,*remaining = fruits
>>> remaining
['watermelon',*remaining = fruits
>>> remaining
['pear',*middle,last = fruits
>>> middle
['pear','watermelon']

8.列表文字中的星號
Python 3.5 通過PEP 448引入了大量的新功能。最大的新功能之一是能夠將可迭代物件轉儲到新列表中。

假設您有一個函式,該函式可以接收任何序列,並返回一個列表,其中該序列與該序列的反序連線在一起:

def palindromify(sequence):
  return list(sequence) + list(reversed(sequence))

該函式需要將事物轉換為列表幾次,以連線列表並返回結果。在Python 3.5中,我們可以改為輸入:

def palindromify(sequence):
   return [*sequence,*reversed(sequence)]

此程式碼刪除了一些不必要的列表呼叫,因此我們的程式碼更加高效和可讀。

這是另一個例子:

def rotate_first_item(sequence):
   return [*sequence[1:],sequence[0]]

該函式返回一個新列表,其中給定列表(或其他序列)中的第一項移動到新列表的末尾。

* 運算子的這種使用是將不同型別的可迭代物件連線在一起的好方法。的*操作者適用於任何可迭代,而使用+操作者僅適用於具有所有相同型別的特定序列。

這不僅限於建立列表。我們還可以將可迭代項轉儲到新的元組或集合中:

>>> fruits = ['lemon','tomato']
>>> (*fruits[1:],fruits[0])
('pear','lemon')
>>> uppercase_fruits = (f.upper() for f in fruits)
>>> {*fruits,*uppercase_fruits}
{'lemon','TOMATO','LEMON','PEAR','WATERMELON','pear'}

請注意,上面的最後一行獲取一個列表和一個生成器,並將它們轉儲到新集中。在使用之前*,以前沒有一種簡單的方法可以在一行程式碼中做到這一點。以前有一種方法可以做到,但要記住或發現它並不容易:

>>> set().union(fruits,uppercase_fruits)
{'lemon','pear'}

9.字典文字中的雙星號
PEP 448還**允許該運算子用於將鍵/值對從一個字典轉儲到新字典中,從而擴充套件了功能:

>>> date_info = {'year': "2020",'title': 'Symphony No 5'}
>>> all_info = {**date_info,**track_info}
>>> all_info
{'year': '2020','month': '01','day': '01','artist': 'Beethoven','title': 'Symphony No 5'}

例如,我們可以在新增新值的同時複製字典:

>>> date_info = {'year': '2020','day': '7'}
>>> event_info = {**date_info,'group': "Python Meetup"}
>>> event_info
{'year': '2020','day': '7','group': 'Python Meetup'}

或在覆蓋特定值的同時複製/合併字典:

>>> event_info = {'year': '2020','group': 'Python Meetup'}
>>> new_info = {**event_info,'day': "14"}
>>> new_info
{'year': '2020','day': '14','group': 'Python Meetup'}

ref: https://treyhunner.com/2018/10/asterisks-in-python-what-they-are-and-how-to-use-them/

總結

到此這篇關於python中字首運算子 *和 **的用法示例詳解的文章就介紹到這了,更多相關python中 *和 **的用法內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!