列表篇_深,淺拷貝,刪除,反轉,排序

愚 生 _發表於2019-03-28

列表索引

  • 索引(下標)
  • 正索引:從左到右,0開始,為列表內元素編號
  • 負索引:從右到左,從-1開始
  • 正負索引不可超界,否則報錯IndexError
  • 為了方便理解可認為列表從左到右排列,左為下界限,右為上界限

  • 列表通過索引訪問
    • list [index] , index就是索引,使用中括號訪問

例如:

l1 = [A,B,C,D]
  • 那麼列表l1中A,B,C,D元素
    • 正索引依次為:0,1,2,3
    • 負索引依次為:-4,-3,-2,-1

列表查詢

  • index (value,[start,[stop]]
    • 通過值value,從指定區間查詢列表內的元素是否匹配
    • 匹配第一個就立即返回索引
    • 匹配不到,拋異常ValueError
  • count(value)
    • 返回列表匹配value次數
  • 時間複雜度
    • index和count方法都是O(n)
    • O(n)隨著列表資料規模增大效率下降
    • 時間複雜度為O(1)是更為高效的
  • len()
    • 返回列表元素長度(個數)
    • 時間複雜度位O(1)

列表元素修改

  • 索引訪問修改
    • list[index] = value
    • 注意索引不要超界

列表元素增加,插入

  • append(object) -> None
    • 列表尾部追加元素,返回None
    • 返回None意味著沒有新列表產生,就地修改
    • 時間複雜度為O(1)
  • insert(index,object)->None
    • 在指定索引index插入object
    • 返回None意味著沒有新列表產生,就地修改
    • 時間複雜度為O(n)
    • 索引超過上下界
      • 超過上界尾部追加(相當於尾部追加)
      • 超過下界頭部追加(影響極大,後面資料全部右移)

列表元素擴充套件

  • extend(iteratable) -> None
    • 將可迭代物件元素追加進來,返回None
    • 就地修改
  • + -> list
    • 連線操作,將兩個列表連線起來
    • 產生新列表,原列表不變
    • 本質呼叫魔術方法_add_()方法
    • 與extand相比產生新列表,需要申請新的記憶體空間,更佔用記憶體
  • * -> list
    • 重複操作,將本列表元素重複n次,返回新列表

列表刪除元素

  • remove(value) -> None
    • 從左到右查詢第一個匹配value值,移除該元素,返回None
    • 就地修改
    • 會引起資料移動(列表最後一個資料除外),O(n)
  • pop([index]) -> item
    • 不指定索引,從列表尾部彈出一個元素
    • 指定索引index,從索引處彈出一個元素,索引超界拋錯IndexError
    • 指定索引效率低,時間複雜度高O(n)
    • 不置頂索引效率高,時間複雜度低O(1)
    • 不指定索引情況下與append配合使用效率較高
  • clear() -> None
    • 清除列表所有元素,剩下一個空列表
    • 此處並非馬上從記憶體刪除列表內所有元素,而是把各元素引用計數都 -1 ,此列表為空,長度為0,刪除操作由GC完成

列表其他操作

  • reverse() -> None
    • 將列表元素反轉,返回None
    • 就地修改
  • sort(key=None,reverse=False) -> None
    • 對列表元素排序,就地修改,預設升序
    • reverse為Ture,反轉,降序
    • key是一個函式,指定key如何排序
      • lst.sort(key=function)
  • in
    • [3,5] in [1,2,[3,5],6]
    • for x in [1,2,3,6,7]

列表複製

  • copy() -> list
    • shadow copy 返回一個新列表
      • 影子拷貝,也叫淺拷貝,遇到引用型別只是複製一個引用而已
    • 深拷貝
      • copy模組提供了deepcopy
   import copy 


舉個栗子:

    Lst1=[1,[a,b,c],3]
    Lst2=Lst1.copy()
    Lst2=[1,[a,b,c],3]
  • 對於淺拷貝:
    如果我們修改 Lst1[2]=9
    那麼列表 Lst1=[1,[a,b,c],9]
    列表 Lst2=[1,[a,b,c],3]
    修改 Lst1[0] 也是一樣的,列表Lst2 不會受到影響,同理修改 Lst2[0] 和 Lst2[2] 也不會影響列表Lst1
    不過,如果我們修改 Lst1[1]
    這時列表Lst1和列表Lst2都會受到影響
  • 對於深拷貝:
    import.copy
    Lst1=[1,[a,b,c],3]
    Lst2=copy.deepcopy(Lst1)
    Lst2=[1,[a,b,c],3]
  • 如果我們修改 Lst1[2]=9
    那麼列表 Lst1=[1,[a,b,c],9]
    不過列表 Lst2=[1,[a,b,c],3]
    修改 Lst1[0] 也是一樣的,列表Lst2 不會受到影響
    如果我們修改 Lst1[1] ,列表 Lst1 會變化 ,列表 Lst2 不會受到 Lst1 的影響
  • 總結
    1.無論深淺拷貝,修改列表內‘簡單型別’元素,如1,3,都不會對拷貝後的列表產生影響
    2.對於淺拷貝,修改列表內‘複雜型別’元素,如 [a,b,c], 會對拷貝前後兩列表產生影響
    3.對於深拷貝,修改列表內‘複雜型別’元素,如 [a,b,c], 不會對另一個列表產生影響
  • 為了方便理解我簡單做了圖如下:

在這裡插入圖片描述
在這裡插入圖片描述

推薦使用索引操作,非索引操作儘量不用或少用

相關文章