python中的解包可以這樣理解:一個(gè)list是一個(gè)整體,想把list中每個(gè)元素當(dāng)成一個(gè)個(gè)個(gè)體剝離出來,這個(gè)過程就是解包,我們來看下面這些例子(分為12個(gè)部分)。
1.將list中每個(gè)元素賦值給一個(gè)變量
>>> 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
如果可迭代對象包含的元素和前面待賦值變量數(shù)量不一致,則會(huì)報(bào)錯(cuò)。但是可以通過*來表示多個(gè)元素
3.星號(hào)的使用
比如我們要計(jì)算平均分,去除最高分和最低分,除了用切片,還可以用解包的方式獲得中間的數(shù)值
>>> first, *new, last = [94, 85, 73, 46]
>>> new
[85, 73]
用*來表示多個(gè)數(shù)值
4.壓包過程
壓包是解包的逆過程,用zip函數(shù)實(shí)現(xiàn),下面例子可以對壓包有一個(gè)直觀的感受
>>> a = ['a', 'b', 'c']
>>> b = [1, 2, 3]
>>> for i in zip(a, b):
... print(i)
...
('a', 1)
('b', 2)
('c', 3)
5.壓包與解包混合的例子
下面例子實(shí)現(xiàn):兩個(gè)列表對應(yīng)數(shù)值相加
>>> a = [0, 1, 2]
>>> b = [1, 2, 3]
>>> for i, j in zip(a, b):
... print(i+j)
...
1
3
5
細(xì)細(xì)拆解上面過程,可以看出步驟是這樣的
先是zip函數(shù)將a b壓包成為一個(gè)可迭代對象
對可迭代對象的每一個(gè)元素(('a', 1))進(jìn)行解包(i, j = ('a', 1))
此時(shí)就可以分別調(diào)用i j變量進(jìn)行計(jì)算
下面我們加入星號(hào)
>>> 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._的用法
當(dāng)一些元素不用時(shí),用_表示是更好的寫法,可以讓讀代碼的人知道這個(gè)元素是不要的
>>> person = ('Bob', 20, 50, (11, 20, 2000))
>>> name, *_, (*_, year) = person
>>> name
'Bob'
>>> year
2000
7.多變量同時(shí)賦值
之前賦值符號(hào)右側(cè)都是可迭代對象,其實(shí)右側(cè)也可以是多個(gè)變量
>>> a, b = 1, 2
>>> a
1
>>> b
2
>>> a = 1, 2
>>> a
(1, 2)
下面用法都會(huì)報(bào)錯(cuò)
*a = 1, 2
a, b, c = 1, 2
可以這樣
*a, = 1, 2
8.*之可變參數(shù)
函數(shù)定義時(shí),我們使用*的可變參數(shù),其實(shí)也是壓包解包過程
>>> def myfun(*num):
... print(num)
...
>>> myfun(1,2,5,6)
(1, 2, 5, 6)
參數(shù)用*num表示,num變量就可以當(dāng)成元組調(diào)用了。
其實(shí)這個(gè)過程相當(dāng)于*num, = 1,2,5,6
9.*之關(guān)鍵字參數(shù)
>>> def myfun(**kw):
... print(kw)
...
>>> myfun(name = "Bob", age = 20, weight = 50)
{'weight': 50, 'name': 'Bob', 'age': 20}
鍵值對傳入**kw,kw就可以表示相應(yīng)字典。
**的用法只在函數(shù)定義中使用,不能這樣使用
a, **b = {'weight': 50, 'name': 'Bob', 'age': 20}
10.可變參數(shù)與關(guān)鍵字參數(shù)的細(xì)節(jié)問題
(1)函數(shù)傳入實(shí)參時(shí),可變參數(shù)(*)之前的參數(shù)不能指定參數(shù)名
>>> def myfun(a, *b):
... print(a)
... print(b)
...
>>> myfun(a=1, 2,3,4)
File "<stdin>", line 1
SyntaxError: positional argument follows keyword argument
>>> myfun(1, 2,3,4)
1
(2, 3, 4)
(2)函數(shù)傳入實(shí)參時(shí),可變參數(shù)(*)之后的參數(shù)必須指定參數(shù)名,否則就會(huì)被歸到可變參數(shù)之中
>>> def myfun(a, *b, c=None):
... print(a)
... print(b)
... print(c)
...
>>> myfun(1, 2,3,4)
1
(2, 3, 4)
None
>>> myfun(1, 2,3,c=4)
1
(2, 3)
4
如果一個(gè)函數(shù)想要使用時(shí)必須明確指定參數(shù)名,可以將所有參數(shù)都放在可變參數(shù)之后,而可變參數(shù)不用管它就可以,也不用命名,如下
>>> def myfun(*, a, b):
... print(a)
... print(b)
...
>>> myfun(a = 1,b = 2)
1
2
可變參數(shù)的這兩條特性,可以用于將 只需要按照位置賦值的參數(shù) 和 需要明確指定參數(shù)名的參數(shù)區(qū)分開來
(3)關(guān)鍵字參數(shù)都只能作為最后一個(gè)參數(shù),前面的參數(shù)按照位置賦值還是名稱賦值都可以
下面展示一個(gè)既用可變參數(shù)有用關(guān)鍵字參數(shù)的例子
>>> def myfun(a, *b, c, **d):
... print(a)
... print(b)
... print(c)
... print(d)
...
>>> myfun(1, 2, 3, c= 4, m = 5, n = 6)
1
(2, 3)
4
{'n': 6, 'm': 5}
(4)可變參數(shù)與關(guān)鍵詞參數(shù)共同使用以表示任意參數(shù)
下面是這一點(diǎn)在裝飾器當(dāng)中的使用
>>> def mydecorator(func):
... def wrapper(*args, **kw):
... print('I am using a decorator.')
... return func(*args, **kw)
... return wrapper
...
>>> @mydecorator
... def myfun(a, b):
... print(a)
... print(b)
...
>>> myfun(1, b = 2)
I am using a decorator.
1
2
(如果有的讀者不熟悉裝飾器,只需要知道,使用@定義myfun相當(dāng)于myfun = mydecorator(myfun),定義出來的myfun其實(shí)是返回結(jié)果wrapper函數(shù))
wrapper函數(shù)使用*args, *kw作為參數(shù),則被修飾的myfun函數(shù)需要的參數(shù)無論是什么樣的,傳入wrapper都不會(huì)報(bào)錯(cuò),這保證了裝飾器可以修飾各種各樣函數(shù)的靈活性。畢竟我們一般在函數(shù)中傳入?yún)?shù)時(shí),要么所有參數(shù)名都寫,要么前面幾個(gè)不寫,后面的會(huì)寫,這樣使用args, **kw完全沒有問題。
11.解包作為參數(shù)傳入函數(shù)中
首先定義一個(gè)函數(shù)
def myfun(a, b):
print(a + b)
列表元組的解包
>>> n = [1, 2]
>>> myfun(*n)
3
>>> m = (1, 2)
>>> myfun(*m)
3
字典的解包
>>> mydict = {'a':1, 'b': 2}
>>> myfun(**mydict)
3
>>> myfun(*mydict)
ba
一個(gè)應(yīng)用
>>> bob = {'name': 'Bob', 'age': 30}
>>> "{name}'s age is {age}".format(**bob)
"Bob's age is 30"
12.多返回值函數(shù)
下面過程也涉及到了解包
def myfun(a, b):
return a + 1, b + 2
>>> m, n = myfun(1, 2)
>>> m
2
>>> n
4
其實(shí)本身是一個(gè)元組
>>> p = myfun(1, 2)
>>> p
(2, 4)
Python學(xué)習(xí)交流群:834179111,群里有很多的學(xué)習(xí)資料。歡迎歡迎各位前來交流學(xué)習(xí)。