Python中的解包(Unpacking)

 

我尽量用少的文字,多的代码,来帮助大家理解Python中的解包。
Talk is cheap, below is the code:

part 1

a = [1, 2, 3]
>>> a
[1, 2, 3]
a, b, c = [1, 2, 3]
>>> a
1
>>> b
2
>>> c
3

part 2

注意下面代码中那个神奇的星号(*):

a, *b = [1, 2, 3]
>>> a
1
>>> b
[2, 3]

*a, b = [1, 2, 3]
>>> a
[1, 2]
>>> b
3
a, *b, c = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a
1
>>> b
[2, 3, 4, 5, 6, 7, 8]
>>> c
9

*a, b, c = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a
[1, 2, 3, 4, 5, 6, 7]
>>> b
8
>>> c
9

a, b, *c = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a
1
>>> b
2
>>> c
[3, 4, 5, 6, 7, 8, 9]

part 3

s = {'hello': 0, 'my': 1, 'world': 2}

def foo(a, b, c):
    print(a)
    print(b)
    print(c)

>>> foo(*s)
hello
my
world

>>> foo(**s)
TypeError: foo() got an unexpected keyword argument 'hello'

def foo_new(hello, my, world):
    print(hello)
    print(my)
    print(world)

>> foo_new(**s)
0
1
2

我们可以发现,如果用一个星号(*)来解包字典的话,我们获取到的其实是字典的“键”,相当于s.keys();如果用两个星号(**)来解包字典,获取到的则是字典中每个键所对应的“值”,相当于s.values()
当我们只用一个星号来解包字典的时候,函数的参数列表中的参数名字并不需要和字典中的键一致;而当我们用两个星号来解包字典的时候,函数的参数列表中的参数名字必须要和字典中的键的名字完全一致,否则在解包过程中,Python解释器将无法在字典中找到对应的键,也就无法输出键所对应的值了。
还有一点需要注意的是,两个星号的解包只能用在函数的参数列表中,而不能用在赋值表达式中。而一个星号的解包则没有这种限制。