在 Python 中,一个元组或列表的元素可以被展开并赋值给多个变量。这被称为序列解包或解包赋值。
这里介绍一下以下细节。
- 图元和列表的解包基础知识
- 嵌套的图元,未打包的列表
- 用下划线进行解包:
_
- 用星号解开包装:
*
关于使用星号来展开和传递图元、列表和字典作为函数参数的信息,请参见下面的文章。
图元和列表的解包基础知识
当变量写在左边,用逗号隔开时,每个变量被分配到右边的元组或列表中的一个元素。这对元组和列表都是一样的(下面的例子是以元组形式写的)。
t = (0, 1, 2)
a, b, c = t
print(a)
print(b)
print(c)
# 0
# 1
# 2
l = [0, 1, 2]
a, b, c = l
print(a)
print(b)
print(c)
# 0
# 1
# 2
注意,由于图元可以省略圆括号,这可以用来在一行中为多个变量分配多个值,如下所示。
a, b = 0, 1
print(a)
print(b)
# 0
# 1
如果变量的数量与元素的数量不一致,就会发生错误。
# a, b = t
# ValueError: too many values to unpack (expected 2)
# a, b, c, d = t
# ValueError: not enough values to unpack (expected 4, got 3)
如果变量的数量少于元素的数量,剩下的元素可以通过在变量名称上附加星号来作为一个列表来分配(见下文)。
嵌套的图元,未打包的列表
嵌套的图元和列表也可以被解包。如果你想把内容也解包,请把变量放在以下其中一个中括起来
()
[]
t = (0, 1, (2, 3, 4))
a, b, c = t
print(a)
print(b)
print(c)
# 0
# 1
# (2, 3, 4)
print(type(c))
# <class 'tuple'>
a, b, (c, d, e) = t
print(a)
print(b)
print(c)
print(d)
print(e)
# 0
# 1
# 2
# 3
# 4
与_underscore_解压。
在Python中,不仅是解压,不需要的值习惯性地分配给下划线(underscore)_。没有特殊的语法含义;它们只是被分配到一个名为_的变量中。
t = (0, 1, 2)
a, b, _ = t
print(a)
print(b)
print(_)
# 0
# 1
# 2
用星号解开包装
如果变量的数量少于元素的数量,变量名称中的星号将导致元素被作为一个列表一起分配。
这个语法从Python 3开始实施,在Python 2中没有。
这些元素被从头到尾分配给没有星号的变量,其余的元素被作为一个列表分配给有星号的变量。
t = (0, 1, 2, 3, 4)
a, b, *c = t
print(a)
print(b)
print(c)
# 0
# 1
# [2, 3, 4]
print(type(c))
# <class 'list'>
a, *b, c = t
print(a)
print(b)
print(c)
# 0
# [1, 2, 3]
# 4
*a, b, c = t
print(a)
print(b)
print(c)
# [0, 1, 2]
# 3
# 4
例如,如果你想只把一个元组或列表的前两个元素分配给一个变量,你可能会对不需要的部分使用上述下划线。
a, b, *_ = t
print(a)
print(b)
print(_)
# 0
# 1
# [2, 3, 4]
同样也可以写成如下
a, b = t[0], t[1]
print(a)
print(b)
# 0
# 1
只能附加一个星号。如果有多个标有星号的变量,将产生一个SyntaxError错误,因为无法确定有多少元素被分配给每个变量。
# *a, b, *c = t
# SyntaxError: two starred expressions in assignment
请注意,即使是分配给标有星号的变量的单个元素也会被分配为一个列表。
t = (0, 1, 2)
a, b, *c = t
print(a)
print(b)
print(c)
# 0
# 1
# [2]
print(type(c))
# <class 'list'>
如果没有多余的元素,就会分配一个空列表。
a, b, c, *d = t
print(a)
print(b)
print(c)
print(d)
# 0
# 1
# 2
# []