盤點 Python 10 大常用數(shù)據(jù)結(jié)構(gòu)(上篇)
Python 常用數(shù)據(jù)結(jié)構(gòu)學習目的
這個專題,盡量使用最精簡的文字,借助典型案例盤點Python常用的數(shù)據(jù)結(jié)構(gòu)。
如果你還處于Python入門階段,通常只需掌握list、tuple、set、dict這類數(shù)據(jù)結(jié)構(gòu),做到靈活使用即可。
然而,隨著學習的深入,平時遇到實際場景變復雜,很有必要去了解Python內(nèi)置的更加強大的數(shù)據(jù)結(jié)構(gòu)deque、heapq、Counter、OrderedDict、defaultDict、ChainMap,掌握它們,往往能讓你少寫一些代碼且能更加高效的實現(xiàn)功能。
我的施工之路
學習目標
- 學習數(shù)據(jù)結(jié)構(gòu)第一階段:掌握它們的基本用法,使用它們解決一些基本問題;
- 學習第二階段:知道何種場景選用哪種最恰當?shù)臄?shù)據(jù)結(jié)構(gòu),去解決題問題;
- 學習第三階段:了解內(nèi)置數(shù)據(jù)結(jié)構(gòu)的背后源碼實現(xiàn),與《算法和數(shù)據(jù)結(jié)構(gòu)》這門學問里的知識聯(lián)系起來,打通任督二脈。
下面根據(jù)定義的這三個階段,總結(jié)以下10種最常用的數(shù)據(jù)結(jié)構(gòu):
1. list
基本用法 廢話不多說,在前面單獨有一個專題詳述了list的使用列表專題
使用場景 list 使用在需要查詢、修改的場景,極不擅長需要頻繁插入、刪除元素的場景。
實現(xiàn)原理 list對應數(shù)據(jù)結(jié)構(gòu)的線性表,列表長度在初始狀態(tài)時無需指定,當插入元素超過初始長度后再啟動動態(tài)擴容,刪除時尤其位于列表開始處元素,時間復雜度為O(n)
2. tuple
元組是一類不允許添加刪除元素的特殊列表,也就是一旦創(chuàng)建后續(xù)決不允許增加、刪除、修改。
基本用法 元組大量使用在打包和解包處,如函數(shù)有多個返回值時打包為一個元組,賦值到等號左側(cè)變量時解包。
- In [22]: t=1,2,3
- In [23]: type(t)
- Out[23]: tuple
實際創(chuàng)建一個元組實例
使用場景 如果非常確定你的對象后面不會被修改,則可以大膽使用元組。為什么?因為相比于list, tuple實例更加節(jié)省內(nèi)存,這點尤其重要。
- In [24]: from sys import getsizeof
- In [25]: getsizeof(list())
- Out[25]: 72 # 一個list實例占用72個字節(jié)
- In [26]: getsizeof(tuple())
- Out[26]: 56 # 一個tuple實例占用56個字節(jié)
所以創(chuàng)建100個實例,tuple能節(jié)省1K多字節(jié)。
3. set
基本用法 set是一種里面不能含有重復元素的數(shù)據(jù)結(jié)構(gòu),這種特性天然的使用于列表的去重。
- In [27]: a=[3,2,5,2,5,3]
- In [28]: set(a)
- Out[28]: {2, 3, 5}
除此之外,還有知道set結(jié)構(gòu)可用于兩個set實例的求交集、并集、差集等操作。
- In [29]: a = {2,3,5}
- In [30]: b = {3,4,6,2}
- In [31]: a.intersection(b) # 求交集
- Out[31]: {2, 3}
使用場景 如果只是想緩存某些元素值,且要求元素值不能重復時,適合選用此結(jié)構(gòu)。并且set內(nèi)允許增刪元素,且效率很高。
實現(xiàn)原理 set在內(nèi)部將值哈希為索引,然后按照索引去獲取數(shù)據(jù),因此刪除、增加、查詢元素效果都很高。
4. dict
基本用法 dict 是Python中使用最頻繁的數(shù)據(jù)結(jié)構(gòu)之一,字典創(chuàng)建由通過dict函數(shù)、{}寫法、字典生成式等,增刪查元素效率都很高。
- d = {'a':1,'b':2} # {}創(chuàng)建字典
- # 列表生成式
- In [38]: d = {a:b for a,b in zip(['a','b'],[1,2])}
- In [39]: d
- Out[39]: {'a': 1, 'b': 2}
使用場景 字典尤其適合在查詢多的場景,時間復雜度為O(1). 如leetcode第一題求解兩數(shù)之和時,就會使用到dict的O(1)查詢時間復雜度。
同時,Python類中屬性值等信息也都是緩存在__dict__這個字典型數(shù)據(jù)結(jié)構(gòu)中。
但是值得注意,dict占用字節(jié)數(shù)是list、tuple的3、4倍,因此對內(nèi)存要求苛刻的場景要慎重考慮。
- In [40]: getsizeof(dict())
- Out[40]: 248
實現(xiàn)原理 字典是一種哈希表,同時保存了鍵值對。
以上4種數(shù)據(jù)結(jié)構(gòu)相信大家都已經(jīng)比較熟悉,因此我言簡意賅的介紹一遍。接下來再詳細的介紹下面6種數(shù)據(jù)結(jié)構(gòu)及各自使用場景,會列舉更多的例子。
- 5. deque
- 6. Counter
- 7. OrderedDict
- 8. heapq
- 9. defaultdict
- 10. ChainMap