Python字典順序儲存原理解析

2021-10-18 20:45:21 字數 2380 閱讀 7835

在刷題的時候看到很多時候題目要用到ordereddict,不是很理解這樣做的目的,看到解析說是要按照插入的順序儲存和取出。當時就很疑惑,親自試驗了預設的dict也能夠實現順序儲存和取出。

在3.6版本之前,python dict底層在初始建立的時候採用的是indice和儲存合併在乙個二維陣列當中。dictionary採用雜湊表原理,key作為取值物件,進行hash(key)操作,得到雜湊值,然後用值進行 % 字典容量得到要插入的位置。

my_dict[

'age']=

26my_dict[

'salary']=

999999

## dictionary結構[[

-4234469173262486640

, 指向salary的指標, 指向999999的指標],[

1545085610920597121

, 執行age的指標, 指向26的指標],[

---,

---,

---]

,[--

-,--

-,--

-],[

---,

---,

---]

,[1278649844881305901

, 指向name的指標, 指向kingname的指標],[

---,

---,

---]

,[--

-,--

-,--

-]]

取值 和存放都是進行hash然後取模,直接訪問這個二位陣列。當你要迴圈遍歷字典的key的時候,python底層會遍歷這個二維陣列,如果當前行有資料,那麼就返回key指標對應的記憶體裡面的值。如果當前行沒有資料,那麼就跳過。所以總是會遍歷整個二位陣列的每一行。

每一行有三列,每一列占用8byte的記憶體空間,所以每一行會占用24byte的記憶體空間。

由於hash值取餘數以後,餘數可大可小,所以字典的key並不是按照插入的順序存放的

開放定址,當兩個不同的key,經過hash以後,再對8取餘數,可能餘數會相同。此時python為了不覆蓋之前已有的值,就會使用開放定址技術重新尋找乙個新的位置存放這個新的鍵值對。

當字典的鍵值對數量超過當前陣列長度的2/3時,陣列會進行擴容,8行變成16行,16行變成32行。長度變了以後,原來的餘數字置也會發生變化,此時就需要移動原來位置的資料,導致插入效率變低。

在版本3.6之後,字典的底層資料結構發生了變化,現在當你初始化乙個空的字典以後,它在底層是這樣的:

my_dict[

'address']=

'***'

my_dict[

'salary']=

999999

## 此時的記憶體示意圖

indices =[1

,0,none

,none

,none

,none,2

,none

]entries =[[

-5954193068542476671

, 指向name的指標, 執行kingname的指標],[

9043074951938101872

, 指向address的指標,指向***的指標],[

7324055671294268046

, 指向salary的指標, 指向999999的指標]

]

實際資料儲存和索引進行分開存放,indices是資料存放在二維陣列的位置,其他內容保持不變。這樣就保證了dictionary在新增新的鍵值對的時候是按照順序進行依次存放的。當去讀取dict內容的時候

>>

>

hash

('salary'

)7324055671294268046

>>

>

hash

('salary')%

86

那麼我就去讀indices下標為6的這個值。這個值為2.

然後再去讀entries裡面,下標為2的這一行的資料,也就是salary對應的資料了。

新的這種方式,當我要插入新的資料的時候,始終只是往entries的後面新增資料,這樣就能保證插入的順序。當我們要遍歷字典的keys和values的時候,直接遍歷entries即可,裡面每一行都是有用的資料,不存在跳過的情況,減少了遍歷的個數。

老的方式,當二維陣列有8行的時候,即使有效資料只有3行,但它占用的記憶體空間還是 8 * 24 = 192 byte。但使用新的方式,如果只有三行有效資料,那麼entries也就只有3行,占用的空間為3 * 24 =72 byte,而indices由於只是乙個一維的陣列,只占用8 byte,所以一共占用 80 byte。記憶體占用只有原來的41%。

Python 字典理解

目錄 初始化乙個空字典 給字典增加一對 鍵 值 key value 使用鍵來呼叫值 改變字典裡的值 字典是物件引用 字典對鍵和值的迭代 參考 obj print obj output 字典的鍵和值之間存在一一對映關係,且 鍵 值對 在字典中的放置是毫無順序的 obj obj one 1 obj tw...

Python字典的原理

python中dict物件是表明了其是乙個原始的python資料型別,按照鍵值對的方式儲存,其中文名字翻譯為字典,顧名思義其通過鍵名查詢對應的值會有很高的效率,時間複雜度在常數級別o 1 本文針對其實現的資料結構進行原理性說明和拓展,不涉及python的原始碼剖析。dict底層實現 在python2...

Python 字典實現原理

a a key1 1 a key2 6 del a key1 python直譯器 執行 a python直譯器讀到這裡,比如會給5個連續的記憶體空間,有5個連續的記憶體位址,可以放資料 python直譯器 執行 a key1 1 這裡,python直譯器會對key1進行雜湊運算,得到乙個十位進製的雜...