1.列表概述
僅僅從操作方式上看,列表像是數組和鏈表的結合體,除按照索引訪問外,還支持插入,追加,刪除等操作.完全可當做隊列或者棧進行使用.如果不考慮性能問題,列表視乎是一種易用且功能完善的理想數據結構.
```python
In [1]: x= [1, 2]
In [2]: x[1]
Out[2]: 2
In [3]: x.insert(0,0) # 插入數據
In [4]: x
Out[4]: [0, 1, 2]
In [5]: x.reverse() # 反轉
In [6]: x
Out[6]: [2, 1, 0]
```
queue
```python
In [7]: q = []
In [8]: q.append(1) # 在列表最後插入一個數據
In [9]: q.append(2)
In [10]: q
Out[10]: [1, 2]
In [11]: q.pop() # 清除追加順序彈出數據
Out[11]: 2
In [12]: q.pop()
Out[12]: 1
In [13]: q
Out[13]: []
```
***
如果有大量寫操作,建議使用 collections,queue 類型
***
列表的內部結構是由兩部分組成,保存元素數量和內存分配計數的頭部,以及儲存元素指針的獨立數組.所有元素項使用該數組保存指針引用,並不嵌入內容.
***
作為使用頻率最高的數據結構之一,列表的性能優化很重要,固定長度的頭部結構,很容易實現內存複用.創建時,有限從複用區獲取.被揮手時,除非超出複用數量限制(80) ,否則會被放回服用去,而非交還內存,每次真正需要分配和釋放的是指針數組.
用數組而非鏈表存儲元素項引用,也有實際考慮.從讀操作開看,無論遍歷還是基於序號訪問,數組性能總是最高的.儘管插入,刪除,等變更操作需要移動內存,但也僅僅是指針複製,無論元素大小,不會有太高消耗,如果列表太大,或者寫操作多餘讀,那麼應該使用針對性的數據結構操作.
***
2.構建
顯示指定元素構建語法最為常用,也可基於創建類型,接受可迭代對象作為初始內容,不同於數組,列表僅存儲指針,而對元素內容毫不關心,如此,可以是不同類型混合.
```python
In [14]: [1,"abc",3.14]
Out[14]: [1, 'abc', 3.14]
In [16]: list("abc")
Out[16]: ['a', 'b', 'c']
In [17]: list(range(3))
Out[17]: [0, 1, 2]
```
另外有被稱之為列表推導式的語法,同樣適用括號,但是以for循環初始化元素,並且可以選擇if作為過濾條件.
```python
In [1]: class A(list):
...: pass
...:
In [2]: type(A('abc')+ list('del')) # 返回的是list而不是a
Out[2]: list
In [3]: class B(collections.UserList):
...: pass
In [4]: type(B("abc") + list("del")) # 返回了B類型
Out[4]: __main__.B
```
***
最小接口設計是一個基本原則,應該慎重考慮這種功能的類型是否適合作為基類.
3.操作
用加法運算符鏈接多個列表,乘法賦值內容
```python
In [9]: [1, 2] + [3, 4]
Out[9]: [1, 2, 3, 4]
In [10]: [1, 2] * 2
Out[10]: [1, 2, 1, 2]
```
注意,同時加法(或者減法) 運算,但是結果可能會不同.
```python
In [12]: a = [1, 2]
In [13]: b = a
In [14]: a = a + [3, 4] # 新建列表對象,然後和a關聯
In [15]: a
Out[15]: [1, 2, 3, 4] # a,b結果不同,確定a指向新對象
In [16]: b
Out[16]: [1, 2]
In [17]: a = [1, 2]
In [18]: b = a
In [19]: a += [3, 4] # 直接修改了a的內容
In [20]: a
Out[20]: [1, 2, 3, 4]
In [21]: b # b的內容也隨著更改
Out[21]: [1, 2, 3, 4]
```
> 編譯器將"+=" 運算符處理成INPLACE_ADD操作,也就是修改原函數,而並非建立新對象,其中效果類似於list.extend 方法
判斷元素是否存在,習慣用in,而並非index()方法
```python
in[22]: 2 in [1, 2]
Out[22]: True
```
至於刪除操作,可用索引序號指定單個元素,或者切片指定刪除範圍.
```python
In [23]: a = [0, 1, 2, 3, 4, 5]
In [24]: del a[5] # 刪除單個元素
In [25]: a
Out[25]: [0, 1, 2, 3, 4]
In [26]: del a[1:2] # 刪除範圍元素
In [27]: a
Out[27]: [0, 2, 3, 4]
```
返回切片時創建新列表對象,並且複製相關指針數據到新數組,出所引用目標相同之外,列表自身的修改(增加,刪除) 互不影響
```python
In [32]: a = [0, 2, 4 ,6]
In [33]: b = a[:2] # 複製引用
In [34]: b
Out[34]: [0, 2]
In [35]: a[0] is b[0]
Out[35]: True
In [36]: a.insert(1,1) # 對a列表操作,不會影響b
In [37]: a
Out[37]: [0, 1, 2, 4, 6]
In [38]: b
Out[38]: [0, 2]
```
***
複製的是指針(引用),而並非目標元素對象.
對列表自身的修改互補影響,但是對目標元素對象的修改是共享的
***
### 3.列表排序可以設定條件,比如按照字段或者長度等
```python
In [55]: d = [3,0,2,1]
In [56]: sorted(d) # 同樣可以指定排序條件,或者倒敘
Out[56]: [0, 1, 2, 3]
In [57]: d
Out[57]: [3, 0, 2, 1]
```
4.利用bisect模塊,可向有序列表插入元素,它使用二分法查找合適位置,可以實現優先級隊列或者一致性哈希算法
```python
In [59]: import bisect
In [60]: bisect.insort_left(d,1) # 插入新的元素後,依舊保持有序狀態
In [61]: d
Out[61]: [0, 1, 2, 4]
In [62]: bisect.insort_left(d,2)
In [63]: d
Out[63]: [0, 1, 2, 2, 4]
In [64]: bisect.insort_left(d,3)
In [65]: d
Out[65]: [0, 1, 2, 2, 3, 4]
```
自定義複合類型,可通過重載比較運算符(__eq__,__lt__ 等) 實現自定義排序條件.
文章的最後呢:
最後小編我自己是一名高級python開發工程師,這裡有我自己整理了一套最新的python系統學習教程,包括從基礎的python基礎到web開發、爬蟲、數據分析、數據可視化、機器學習,自動化運維,Linux系統學習等。想要這些資料的可以關注小編,並在後臺私信小編:“01”即可領取。