即便是不起眼的赋值语句也蕴藏着一些使用窍门。
x, y, z = 1, 2, 3
print(x, y, z)
1 2 3
看似用处不大? 使用这种方式还可交换多个变量的值。
x, y = y, x
print(x, y, z)
2 1 3
上面的赋值方式,看起来理所当然。但在 C/C++ 语言中是不能这样交换赋值的。
实际上,这里执行的操作称为序列解包(或可迭代对象解包): 将一个序列(或任何可迭代对象)解包,并将得到的值存储到一系列变量中。 下面用例子进行解释。
values = 1, 2, 3
values
(1, 2, 3)
x, y, z = values
x
1
这在使用返回元组(或其他序列或可迭代对象)的函数或方法时很有用。
假设要从字典中随便获取(或删除)一个键-值对,可使用方法 popitem
,它随便获取一个键-值对并以元组的方式
返回。接下来,可直接将返回的元组解包到两个变量中。
scoundrel = {'name': 'Robin', 'girlfriend': 'Marion'}
key, value = scoundrel.popitem()
key
'girlfriend'
value
'Marion'
这让函数能够返回被打包成元组的多个值,然后通过一条赋值语句轻松地访问这些值。 赋值魔法包的序列包含的元素个数必须与在等号左边列出的目标个数相同,否则Python将引发异常。
# x, y, z = 1, 2 #此段代码会报错
# x, y, z = 1, 2, 3, 4 #此段代码会报错
可使用星号运算符( *
)来接收多余的值,这样无需确保值和变量的个数相同。
如下例所示:
a, b, *rest = [1, 2, 3, 4]
rest
[3, 4]
还可将带星号的变量放在其他位置。
name = "Albus Percival Wulfric Brian Dumbledore"
first, *middle, last = name.split()
middle
['Percival', 'Wulfric', 'Brian']
赋值语句的右边可以是任何类型的序列。 但带星号的变量最终包含的总是一个列表,在变量和值的个数相同时亦如此。
a, *b, c = "abc"
a, b, c
('a', ['b'], 'c')
这种收集方式也可用于函数参数列表中。
x = y = somefunction()
上述代码与下面的代码等价:
y = somefunction()
x = y
请注意,这两条语句可能与下面的语句不等价:
x = somefunction()
y = somefunction()
有关这方面的详细信息,请参阅5.4.6节介绍相同运算符( is )的部分。
x = 2
x += 1
x
3
x *= 2
x
6
增强赋值也可用于其他数据类型(只要使用的双目运算符可用于这些数据类型)。
fnord = 'foo'
fnord += 'bar'
fnord
'foobar'
fnord *= 2
fnord
'foobarfoobar'
通过使用增强赋值,可让代码更紧凑、更简洁,同时在很多情况下的可读性更强。