1. 程式人生 > >給大家分享一篇 python有趣的解包用法

給大家分享一篇 python有趣的解包用法

python中的解包可以這樣理解:一個list是一個整體,想把list中每個元素當成一個個個體剝離出來,這個過程就是解包,我們來看下面這些例子(分為12個部分)。

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

9.*之關鍵字引數

>>> def myfun(**kw):
...     print(kw)
...
>>> myfun(name = "Bob", age = 20, weight = 50)
{'weight': 50, 'name': 'Bob', 'age': 20}

鍵值對傳入**kw,kw就可以表示相應字典。

**的用法只在函式定義中使用,不能這樣使用

a, **b = {'weight': 50, 'name': 'Bob', 'age': 20}

10.可變引數與關鍵字引數的細節問題

(1)函式傳入實參時,可變引數(*)之前的引數不能指定引數名

>>> 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)函式傳入實參時,可變引數(*)之後的引數必須指定引數名,否則就會被歸到可變引數之中

>>> 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

如果一個函式想要使用時必須明確指定引數名,可以將所有引數都放在可變引數之後,而可變引數不用管它就可以,也不用命名,如下

>>> def myfun(*, a, b):
...     print(a)
...     print(b)
...
>>> myfun(a = 1,b = 2)
1
2

可變引數的這兩條特性,可以用於將 只需要按照位置賦值的引數 和 需要明確指定引數名的引數區分開來

(3)關鍵字引數都只能作為最後一個引數,前面的引數按照位置賦值還是名稱賦值都可以

下面展示一個既用可變引數有用關鍵字引數的例子

>>> 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)可變引數與關鍵詞引數共同使用以表示任意引數

下面是這一點在裝飾器當中的使用

>>> 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相當於myfun = mydecorator(myfun),定義出來的myfun其實是返回結果wrapper函式)

wrapper函式使用*args, **kw作為引數,則被修飾的myfun函式需要的引數無論是什麼樣的,傳入wrapper都不會報錯,這保證了裝飾器可以修飾各種各樣函式的靈活性。畢竟我們一般在函式中傳入引數時,要麼所有引數名都寫,要麼前面幾個不寫,後面的會寫,這樣使用*args, **kw完全沒有問題。

11.解包作為引數傳入函式中

首先定義一個函式

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

一個應用

>>> bob = {'name': 'Bob', 'age': 30}
>>> "{name}'s age is {age}".format(**bob)
"Bob's age is 30"

12.多返回值函式

下面過程也涉及到了解包

def myfun(a, b):
    return a + 1, b + 2
>>> m, n = myfun(1, 2)
>>> m
2
>>> n
4

其實本身是一個元組

>>> p = myfun(1, 2)
>>> p
(2, 4)

Python學習交流群:834179111,群裡有很多的學習資料。歡迎歡迎各位前來交流學習。