我们有一个包含N个元素的元组或序列,现在想将它分解为N个单独的变量。
任何序列(或可迭代的对象)都可以通过一个简单的赋值操作来分解为单独的变量。唯一的要求是变量的总数和结构要与序列想吻合。
这中操作在Python中通常叫做拆包/解包(Unpacking)赋值,就是将容器里面的元素逐个取出来放在其他地方。
seq = (1, 2, 3)
num1, num2, num3 = seq
print(num1, num2, num3)
# >>> 1 2 3
data = ['ACME', 50, 91.1, (2012, 12, 21)]
name, shares, price, date = data
print(name, shares, price, date)
# >>> ACME 50 91.1 (2012, 12, 21)
name, shares, price, (year, month, day) = data
print(name, shares, price, year, month, day)
# >>> ACME 50 91.1 2012 12 21
不仅仅是元组或列表,只要对象是可迭代的(实现了__next__
方法的一切对象),就可以执行解包操作的。
s = 'hello'
a, b, c, d, e = s
print(a, b, c, d, e)
# >>> h e l l o
如果接收的元素数量与序列数量不匹配,就会得到一个错误提示。
point = (4, 3)
# x, y, z = point
'''
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: need more than 2 values to unpack
'''
有时候,你可能只想解压一部分数据,丢弃其他的值。对于这种情况Python并没有提供特殊的语法来实现这一点,但是通常可以选一个用不到的变量名,以此来作为要丢弃的值的名称。
data = ['ACME', 50, 91.1, (2012, 12, 21)]
_, shares, price, _ = data
print(shares, price)
# >>> 50 91.1
但是要确保选择的变量名没有在其他地方用到过。
当只想解压序列的前两个值,但序列后面有更多的值,你不能通过用不到的变量名一个一个来赋值,那样代码将变的冗长。
在python3中,支持更高级的解包操作,用星号操作使得等号左边的变量个数可以少于右边迭代对象中元素的个数。
data = ['ACME', 50, 91.1, (2012, 12, 21)]
name, *args, date = data
print(name, args, date)
# >>> ACME [50 91.1], (2012, 12, 21)
基于Nginx+Supervisord+uWSGI+Django1.11.1+Python3.6.5构建