拆包的基本限制之一是您必须事先知道要拆包的序列的长度。
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, [])