>>> a, b, c = [1,2,3]
>>> a
1
>>> b
2
>>> c
3
如果列表中有3个元素,那么刚好可以分配给3个变量。除了列表对象可以解包之外,任何可迭代对象都支持解包,可迭代对象包括元组、字典、集合、字符串、生成器等实现了__next__方法的一切对象。
元组解包
>>> a,b,c = (1,2,3)
>>> a
1
>>> b
2
>>> c
3
字符串解包
>>> a,b,c = "abc"
>>> a
'a'
>>> b
'b'
>>> c
'c'
字典解包
>>> a,b,c = {"a":1, "b":2, "c":3}
>>> a
'a'
>>> b
'b'
>>> c
'c'
字典解包后,只会把字典的 key 取出来,value 则丢掉了。
你可能见过多变量赋值操作,例如:
>>> a, b = 1, 2
>>> a
1
>>> b
2
本质上也是自动解包过程,等号右边其实是一个元组对象 (1, 2),有时候我们代码不小心多了一个逗号 ,,就变成了元组对象
>>> a = 1,
>>> a
(1,)
----------
>>> a = 1
>>> a
1
所以写代码的时候需要特别注意。在 Python 中,交换两个变量非常方便,本质上也是自动解包过程。
>>> a, b = 1, 2
>>> a, b = b, a
>>> a
2
>>> b
1
如果在解包过程中,遇到左边变量个数小于右边可迭代对象中元素的个数时该怎么办? 好比你们家有3口人,你老婆却买了4个苹果,怎么分配呢?
在 Python2 中,如果等号左边变量的个数不等于右边可迭代对象中元素的个数,是不允许解包的。但在 Python3 可以这么做了。这个特性可以在 PEP 3132 中看到。
>>> a, b, *c = [1,2,3,4]
>>> a
1
>>> b
2
>>> c
[3, 4]
>>>
这种语法就是在某个变量面前加一个星号,而且这个星号可以放在任意变量,每个变量都分配一个元素后,剩下的元素都分配给这个带星号的变量
>>> a, *b, c = [1,2,3,4]
>>> a
1
>>> b
[2, 3]
>>> c
4
这种语法有什么好处呢?它使得你的代码写起来更简洁,比如上面例子,在 Python2 中该怎么操作呢?思考3秒钟,再看答案。
>>> n = [1,2,3,4]
# 使用切片操作
>>> a, b, c = n[0], n[1:-1], n[-1]
>>> a
1
>>> b
[2, 3]
>>> c
4
以上是表达式解包的一些操作,接下来介绍函数调用时的解包操作。函数调用时,有时你可能会用到两个符号:星号*和 双星号**。
>>> func(*[1,2,3])
1 2 3
>>> func(*(1,2,3))
1 2 3
>>> func(*"abc")
a b c
>>> func(*{"a":1,"b":2,"c":3})
a b c
函数被调用的时候,使用星号 * 解包一个可迭代对象作为函数的参数。字典对象,可以使用两个星号,解包之后将作为关键字参数传递给函数