python赋值语句(解包赋值、多目标赋值及共享引用)
序列解包赋值语句,赋值一系列整数给一组变量
red,green,blue=range(3)
red,blue
#(0, 2)
元组赋值语句在循环中把序列分割为开头和剩余两部分
l=[1,2,3,4]
while l :
front, l =l[0], l[1:]
print(front, l)
#1 [2, 3, 4]
#2 [3, 4]
#3 [4]
#4 []
扩展的解包的实际应用
序列赋值通常要求左边的目标名称数目与右边的主体中的项数完全一致,如果长度不同,将会得到一个错误
seq=[1,2,3,4]
a,b,c,d=seq
print(a,b,c,d)
#1 2 3 4
然而,在python3中,我们可以在目标中使用带单个星号的名称来更通用地匹配
带单个星号的在右边
a,*b=seq
a
#1
b
#[2, 3, 4]
带单个星号的在左边
*a,b=seq
a
#[1, 2, 3]
b
#4
带单个星号的在中间
a,*b,c=seq
a
#1
b
#[2, 3]
c
#4
带单个星号的在最右边
a,b,*c=seq
a
#1
b
#2
c
#[3, 4]
解包一个字符串中的字符
*在右边
a,*b='spam'
a,b
#('s', ['p', 'a', 'm'])
*在中间
a,*b,c='spam'
a,b,c
#('s', ['p', 'a'], 'm')
*在最右边
a,*b,c='spam'
a,b,c
#('s', ['p', 'a'], 'm')
边界情况
带星号的名称可能只匹配单个的项,但是,总会向其赋值一个列表
seq = [1, 2, 3, 4]
a,b,c,*d=seq
print(a,b,c,d)
#1 2 3 [4]
如果没有剩下的内容可以匹配带星号的名称,会赋值一个空的列表,不管该名称出现在哪里。
a,b,c,d,*e=seq
print(a,b,c,d,e)
#1 2 3 4 []
有多个带星号的名称
a,*b,c,*d=seq
File "<ipython-input-148-fbf1d4ec6eb9>", line 1
a,*b,c,*d=seq
^
SyntaxError: two starred expressions in assignment
值少了,而没有带星号的名称
a,b=seq
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-149-dbe0b5fbb220> in <module>()
----> 1 a,b=seq
ValueError: too many values to unpack (expected 2)
带星号的名称自身没有编写到一个列表中
*a=seq
File "<ipython-input-150-13a1b581088f>", line 1
*a=seq
^
SyntaxError: starred assignment target must be in a list or tuple
正确写法
*a,=seq
a
#[1, 2, 3, 4]
多目标赋值以及共享引用
把变量初始值设为空的可变对象时(诸如列表或字典)
a=b=[]
b.append(42)
a,b
#([42], [42])