本文首发于 知乎
python中的解包可以这样理解:一个list是一个整体,想把list中每个元素当成一个个个体剥离出来,这个过程就是解包,我们来看下面这些例子(分为10个部分)。
1.将list中每个元素赋值给一个变量
>>> name, age, date = ['Bob', 20, '2018-1-1']
>>> name
'Bob'
>>> age
20
>>> date
'2018-1-1'
2.可迭代对象都可以这样做
# 列表
>>> a,b,c = ['a', 'b', 'c']
>>> a
'a'
>>> a,b,c = enumerate(['a', 'b', 'c'])
>>> a
(0, 'a')
# 元组
>>> a,b,c = ('a', 'b', 'c')
>>> a
'a'
# 字典
>>> a,b,c = {'a':1, 'b':2, 'c':3}
>>> a
'a'
>>> a,b,c = {'a':1, 'b':2, 'c':3}.items()
>>> a
('a', 1)
# 字符串
>>> a,b,c = 'abc'
>>> a
'a'
# 生成器
>>>
a,b,c = [x + 1 for x in range(3)]
>>> a
1
如果可迭代对象包含的元素和前面待赋值变量数量不一致,则会报错。但是可以通过
*
来表示多个元素
3.星号的使用
比如我们要计算平均分,去除最高分和最低分,除了用切片,还可以用解包的方式获得中间的数值
>>> first, *new, last = [94, 85, 73, 46]
>>> new
[85, 73]
用
*
来表示多个数值
4.压包过程
压包是解包的逆过程,用zip函数实现,下面例子可以对压包有一个直观的感受
>>> a = ['a', 'b', 'c']
>>> b = [1, 2, 3]
>>> for i in zip(a, b):
... print(i)
...
('a', 1)
('b', 2)
('c', 3)
5.压包与解包混合的例子
下面例子实现:两个列表对应数值相加
>>> a = [0, 1, 2]
>>> b = [1, 2, 3]
>>> for i, j in zip(a, b):
... print(i+j)
...
1
3
5
细细拆解上面过程,可以看出步骤是这样的
-
先是
zip
函数将a b
压包成为一个可迭代对象 -
对可迭代对象的每一个元素(
('a', 1)
)进行解包(i, j = ('a', 1)
) -
此时就可以分别调用
i j
变量进行计算
下面我们加入星号
>>> l = [('Bob', '1990-1-1', 60),
... ('Mary', '1996-1-4', 50),
... ('Nancy', '1993-3-1', 55),]
>>> for name, *args in l:
... print(name, args)
...
Bob ['1990-1-1', 60]
Mary ['1996-1-4', 50]
Nancy ['1993-3-1', 55]
6.
_
的用法
当一些元素不用时,用
_
表示是更好的写法,可以让读代码的人知道这个元素是不要的
>>> person = ('Bob', 20, 50, (11, 20, 2000))
>>> name, *_, (*_, year) = person
>>> name
'Bob'
>>> year
2000
7.多变量同时赋值
之前赋值符号右侧都是可迭代对象,其实右侧也可以是多个变量
>>> a, b = 1, 2
>>> a
1
>>> b
2
>>> a = 1, 2
>>> a
(1, 2)
下面用法都会报错
*a = 1, 2
a, b, c = 1, 2
可以这样
*a, = 1, 2
8.
*
之可变参数
函数定义时,我们使用
*
的可变参数,其实也是压包解包过程
>>> def myfun(*num):
... print(num)
...
>>> myfun(1,2,5,6)
(1, 2, 5, 6)
参数用
*num
表示,
num
变量就可以当成元组调用了。
其实这个过程相当于
*num, = 1,2,5,6