如何在Python中使用星號表示式解包?


簡介

解包的一個基本限制是,你必須預先知道要解包的序列的長度。

如何操作……

random_numbers = [0, 1, 5, 9, 17, 12, 7, 10, 3, 2]
random_numbers_descending = sorted(random_numbers, reverse=True)
print(f"Output \n*** {random_numbers_descending}")

輸出

*** [17, 12, 10, 9, 7, 5, 3, 2, 1, 0]

如果我現在想找出這些數字中最大和第二大的數字,我們會得到一個異常“太多值需要解包”。

print(f"Output \n*** Getting the largest and second largest")
largest, second_largest = random_numbers_descending

輸出

*** Getting the largest and second largest


---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
in
1 print(f"Output \n*** Getting the largest and second largest")
----> 2 largest, second_largest = random_numbers_descending

ValueError: too many values to unpack (expected 2)

Python經常依賴於索引和切片。例如,如果我想從下面的專案列表中提取最大值和第二大值,我們可以這樣做。

largest = random_numbers_descending[0]
print(f"Output \n*** Getting the largest - {largest}")

輸出

*** Getting the largest - 17


second_largest = random_numbers_descending[1]
print(f"Output \n*** Getting the second largest - {second_largest}")

輸出

*** Getting the second largest - 12


rest_of_numbers = random_numbers_descending[2:]
print(f"Output \n*** Getting the rest of numbers - {rest_of_numbers}")

輸出

*** Getting the rest of numbers - [10, 9, 7, 5, 3, 2, 1, 0]

雖然這有效,但所有的索引和切片在視覺上都很冗餘。實際上,以這種方式將序列的成員分成不同的子集很容易出錯。

為了更好地做到這一點,Python 透過星號表示式支援萬用字元解包。

這種星號語法允許解包賦值的一部分接收與解包模式的任何其他部分都不匹配的所有值。

largest,second_largest, *rest_of_numbers = random_numbers_descending
print(f"Output \n largest: {largest} \n second_largest:{second_largest} \n rest_of_numbers:{rest_of_numbers}")

輸出

largest: 17
second_largest:12
rest_of_numbers:[10, 9, 7, 5, 3, 2, 1, 0]

上面的程式碼看起來如何?在一行程式碼中,我們能夠更容易地讀取並實現輸出。星號表示式可以出現在任何位置,因此您可以隨時獲得萬用字元解包的好處,只要您需要提取一個切片。

largest: 17
rest_of_numbers:[12, 10, 9, 7, 5, 3, 2, 1]
smallest:0


*rest_of_numbers, second_smallest, smallest = random_numbers_descending
print(f"Output \n rest_of_numbers:{rest_of_numbers} \n second_smallest: {second_smallest} \n smallest:{smallest}")


rest_of_numbers:[17, 12, 10, 9, 7, 5, 3, 2]
second_smallest: 1
smallest:0

但是,要解包包含星號表示式的賦值,您必須至少有一個必需的部分,否則您將得到一個SyntaxError。我們不能單獨使用萬用字元表示式。

*rest_of_numbers = random_numbers_descending


File "", line 1
*rest_of_numbers = random_numbers_descending
^
SyntaxError: starred assignment target must be in a list or tuple

我們也不能在一個單層解包模式中使用多個萬用字元表示式。這是另一個需要考慮的重要說明。

*rest_of_numbers, *more_smallest, smallest = random_numbers_descending


File "", line 1
*rest_of_numbers, *more_smallest, smallest = random_numbers_descending
^
SyntaxError: two starred expressions in assignment


但是,只要它們是正在解包的多層結構的不同部分的萬用字元,就可以在一個解包賦值語句中使用多個星號表示式。

player_grandslame_and_atptitles = {
'Federer': (20, 103),
'Nadal': (20,84),}

((player1, (grandslam1, *atptitles1)), (player2, (grandslam2, *atptitles2))) = player_grandslame_and_atptitles.items()

print(f'Output \nPlayer - {player1} Have acheived {grandslam1} grandslams and , {atptitles1} atp tour titles')
print(f'Player - {player2} Have acheived {grandslam2} grandslams and , {atptitles2} atp tour titles')


輸出


Player - Federer Have acheived 20 grandslams and , [103] atp tour titles
Player - Nadal Have acheived 20 grandslams and , [84] atp tour titles

星號表示式在所有情況下都成為列表例項。如果要解包的序列中沒有剩餘的專案,則萬用字元部分將是一個空列表。當您處理一個預先知道至少有 N 個元素的序列時,這尤其有用。

random_numbers = [0, 1]
first, second, *rest = random_numbers
print(f"Output \n{first, second, rest}")

輸出

(0, 1, [])

更新於:2020年11月9日

瀏覽量 1K+

啟動你的職業生涯

透過完成課程獲得認證

開始學習
廣告