如何在 Python 中使用星号表达式解包?

pythonserver side programmingprogramming更新于 2026/2/15 4:28:17

简介

解包的基本限制之一是您必须提前知道要解包的序列的长度。

如何做到这一点..

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

我们也不能在单级解包模式中使用多个 catch-all 表达式。这是另一个需要考虑的重要事项。

*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, [])

相关文章


有用资源