<4>Python切片功能剖析

深圳-風塵發表於2019-01-15

引用文章:https://mp.weixin.qq.com/s/NZ371nKs_WXdYPCPiryocw

 

切片基礎法則:

1)公式[i : n : m]i為起始位置索引(i首位0可省略)i+n為結束位置索引(n長度len(li)可省略)m為步長,預設1,禁止0

2i, n同號:從序列的第i位索引起,向右取n-i位,按m間隔過濾。

        i, n異號:從序列的第i位索引起,向右取(len(list)-n)-i位,按m間隔過濾。

 

切片法則推導:

1)當m>0,且 i>0 時:從第 i 位起,取 n-i 位元素(i, n同號)  |   (lenlist)-n)-i 位元素(i, n異號)

2)當m>0,且 i<0 時:從倒數第 |i| 位起,取 n-i 位元素(i, n同號)  |   (n-len(list))-i 位元素(i, n異號)

3)當m<0 i>0 時:先翻轉列表,從第 i 位起,取 n-i 位元素(i, n同號)  |   (lenlist)-n)-i 位元素(i, n異號)

3)當m<0 i<0 時:先翻轉列表,從倒數第 |i| 位起,取 n-i 位元素(i, n同號)  |   (n-len(list))-i 位元素(i, n異號)

 

表示整個列表:其中 X >= len(li)

li[0:X] == li[0:] == li[:X] == li[:] == li[::] == li[-X:X] == li[-X:]

 

切片高階法則:

切片的返回結果:一個新的序列,佔用新的記憶體地址,是屬於淺拷貝

 1 #: 切片返回新的序列,佔用新的記憶體地址
 2 In[2]: li = [1,2,3,4]
 3 In[3]: lo=li[::]
 4 In[4]: id(li)
 5 Out[4]: 2316742428488
 6 In[5]: id(lo)
 7 Out[5]: 2316740137416
 8 
 9 #: 切片屬於淺拷貝
10 In[6]: lii = [1, [2,3,4], 3, 4]
11 In[7]: loo = lii[:2]
12 In[8]: id(lii[1])
13 Out[8]: 2316742399880
14 In[9]: id(loo[1])
15 Out[9]: 2316742399880

 

給切片賦值可迭代物件,可以達到列表實現拼接、替換的操作

列表拼接:使用純佔位符將兩個列表拼接成一個列表

In[2]: li = [1, 2, 3, 4]

#: 拼接到頭部
In[3]: li[:0] = [0]
In[4]: li
Out[4]: [0, 1, 2, 3, 4]

#: 拼接到尾部
In[5]: li[len(li):] = [5, 7]
In[6]: li
Out[6]: [0, 1, 2, 3, 4, 5, 7]

#:拼接到中部
In[7]: li[6:6] = [6]
In[8]: li
Out[8]: [0, 1, 2, 3, 4, 5, 6, 7]

 

 

列表替換:使用非純佔位符將一個列表的部分內容替換為另一個列表內容

 1 In[2]: li = [1, 2, 3, 4]
 2 
 3 #: 頭部替換
 4 In[3]: li[:3] = [7, 8, 9]
 5 In[4]: li
 6 Out[4]: [7, 8, 9, 4]
 7 
 8 #: 尾部替換
 9 In[5]: li[3:] = [5, 6, 7]
10 In[6]: li
11 Out[6]: [7, 8, 9, 5, 6, 7]
12 
13 #: 中部替換
14 In[7]: li[2:4] = [`a`, `b`]
15 In[8]: li
16 Out[8]: [7, 8, `a`, `b`, 6, 7]
17 
18 #: 非等長替換
19 In[9]: li[2:4] = [1, 2, 3, 4]
20 In[10]: li
21 Out[10]: [7, 8, 1, 2, 3, 4, 6, 7]
22 
23 In[11]: li[2:6] = [`a`]
24 In[12]: li
25 Out[12]: [7, 8, `a`, 6, 7]
26 
27 del li[2:3]  # [7, 8, 6, 7]

 

 

自定義切片的功能:__getitem__() 方法用於切片功能

 

怎麼判斷一個物件是否實現了這個方法呢?

1 hasattr(`abc`, `__getitem__`)

 

迭代、迭代物件、迭代器?

迭代:是一種遍歷容器型別物件(例如字串、列表、字典等等)的方式。

迭代物件:實現__iter__() 魔術方法的物件都是可迭代物件。

迭代器:

  •  可迭代物件不等於迭代器
  •  可迭代物件可以變為迭代器

  “一同兩不同,兩者都有__iter__(),迭代物件的__getitem__()變為__next__()就成為跌倒器

  可迭代物件只能被它遍歷,迭代器卻還可以自遍歷

 

要實現迭代器擁有切片的功能?新增__getitem__() 方法。

通過藉助 itertools 模組 islice() 方法,我們能實現迭代器切片,將兩者的優勢相結合,其主要用途在於擷取大型迭代器(如無限數列、超大檔案等等)的片段,實現精準的處理,從而大大地提升效能與效率。

 

相關文章