精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

深入Python字典的內部實現

開發 后端
在Python中,字典是通過哈希表實現的。也就是說,字典是一個數組,而數組的索引是鍵經過哈希函數處理后得到的。哈希函數的目的是使鍵均勻地分布在數組中。由于不同的鍵可能具有相同的哈希值,即可能出現沖突,高級的哈希函數能夠使沖突數目最小化。

字典是通過鍵(key)索引的,因此,字典也可視作彼此關聯的兩個數組。下面我們嘗試向字典中添加3個鍵/值(key/value)對: 

  1. >>> d = {'a': 1, 'b': 2} 
  2.  
  3. >>> d['c'] = 3 
  4.  
  5. >>> d 
  6.  
  7. {'a': 1, 'b': 2, 'c': 3}  

這些值可通過如下方法訪問:

  1. >>> d['a'
  2.  
  3.  
  4. >>> d['b'
  5.  
  6.  
  7. >>> d['c'
  8.  
  9.  
  10. >>> d['d'
  11.  
  12. Traceback (most recent call last): 
  13.  
  14.   File "<stdin>", line 1, in <module> 
  15.  
  16. KeyError: 'd'  

由于不存在 'd' 這個鍵,所以引發了KeyError異常。

哈希表(Hash tables)

在Python中,字典是通過哈希表實現的。也就是說,字典是一個數組,而數組的索引是鍵經過哈希函數處理后得到的。哈希函數的目的是使鍵均勻地分布在數組中。由于不同的鍵可能具有相同的哈希值,即可能出現沖突,高級的哈希函數能夠使沖突數目最小化。Python中并不包含這樣高級的哈希函數,幾個重要(用于處理字符串和整數)的哈希函數通常情況下均是常規的類型:

  1. >>> map(hash, (0, 1, 2, 3)) 
  2.  
  3. [0, 1, 2, 3] 
  4.  
  5. >>> map(hash, ("namea""nameb""namec""named")) 
  6.  
  7. [-1658398457, -1658398460, -1658398459, -1658398462]  

在以下的篇幅中,我們僅考慮用字符串作為鍵的情況。在Python中,用于處理字符串的哈希函數是這樣定義的:

  1. arguments: string object 
  2.  
  3. returns: hash 
  4.  
  5. function string_hash: 
  6.  
  7.     if hash cached: 
  8.  
  9.         return it 
  10.  
  11.     set len to string's length 
  12.  
  13.     initialize var p pointing to 1st char of string object 
  14.  
  15.     set x to value pointed by p left shifted by 7 bits 
  16.  
  17.     while len >= 0: 
  18.  
  19.         set var x to (1000003 * x) xor value pointed by p 
  20.  
  21.         increment pointer p 
  22.  
  23.     set x to x xor length of string object 
  24.  
  25.     cache x as the hash so we don't need to calculate it again 
  26.  
  27.     return x as the hash  

如果在Python中運行 hash('a') ,后臺將執行 string_hash()函數,然后返回 12416037344 (這里我們假設采用的是64位的平臺)。

如果用長度為 x 的數組存儲鍵/值對,則我們需要用值為 x-1 的掩碼計算槽(slot,存儲鍵/值對的單元)在數組中的索引。這可使計算索引的過程變得非常迅速。字典結構調整長度的機制(以下會詳細介紹)會使找到空槽的概率很高,也就意味著在多數情況下只需要進行簡單的計算。假如字典中所用數組的長度是 8 ,那么鍵'a'的索引為:hash('a') & 7 = 0,同理'b'的索引為 3 ,'c'的索引為 2 , 而'z'的索引與'b'相同,也為 3 ,這就出現了沖突。

 

可以看出,Python的哈希函數在鍵彼此連續的時候表現得很理想,這主要是考慮到通常情況下處理的都是這類形式的數據。然而,一旦我們添加了鍵'z'就會出現沖突,因為這個鍵值并不毗鄰其他鍵,且相距較遠。

當然,我們也可以用索引為鍵的哈希值的鏈表來存儲鍵/值對,但會增加查找元素的時間,時間復雜度也不再是 O(1) 了。下一節將介紹Python的字典解決沖突所采用的方法。

開放尋址法( Open addressing )

開放尋址法是一種用探測手段處理沖突的方法。在上述鍵'z'沖突的例子中,索引 3 在數組中已經被占用了,因而需要探尋一個當前未被使用的索引。增加和搜尋鍵/值對需要的時間均為 O(1)。

搜尋空閑槽用到了一個二次探測序列(quadratic probing sequence),其代碼如下:

  1. j = (5*j) + 1 + perturb; 
  2.  
  3. perturb >>= PERTURB_SHIFT; 
  4.  
  5. use j % 2**i as the next table index;  

循環地5*j+1可以快速放大不影響初始索引的哈希值二進位的微小差異。變量perturb可使其他二進位也不斷變化。

出于好奇,我們來看一看當數組長度為 32 時的探測序列,j = 3 -> 11 -> 19 -> 29 -> 5 -> 6 -> 16 -> 31 -> 28 -> 13 -> 2…

關于探測序列的更多介紹可以參閱dictobject.c的源碼。文件的開頭包含了對探測機理的詳細介紹。

 

下面我們結合例子來看一看 Python 內部代碼。

基于C語言的字典結構

以下基于C語言的數據結構用于存儲字典的鍵/值對(也稱作 entry),存儲內容有哈希值,鍵和值。PyObject 是 Python 對象的一個基類。

  1. typedef struct { 
  2.  
  3.     Py_ssize_t me_hash; 
  4.  
  5.     PyObject *me_key; 
  6.  
  7.     PyObject *me_value 
  8.  
  9. } PyDictEntry;  

下面為字典對應的數據結構。其中,ma_fill為活動槽以及啞槽(dummy slot)的總數。當一個活動槽中的鍵/值對被刪除后,該槽則被標記為啞槽。ma_used為活動槽的總數。ma_mask值為數組的長度減 1 ,用于計算槽的索引。ma_table為數組本身,ma_smalltable為長度為 8 的初始數組。

  1. typedef struct _dictobject PyDictObject; 
  2.  
  3. struct _dictobject { 
  4.  
  5.     PyObject_HEAD 
  6.  
  7.     Py_ssize_t ma_fill; 
  8.  
  9.     Py_ssize_t ma_used; 
  10.  
  11.     Py_ssize_t ma_mask; 
  12.  
  13.     PyDictEntry *ma_table; 
  14.  
  15.     PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash); 
  16.  
  17.     PyDictEntry ma_smalltable[PyDict_MINSIZE]; 
  18.  
  19. };  

字典初始化

字典在初次創建時將調用PyDict_New()函數。這里刪掉了源代碼中的部分行,并且將C語言代碼轉換成了偽代碼以突出其中的幾個關鍵概念。

  1. returns new dictionary object 
  2.  
  3. function PyDict_New: 
  4.  
  5.     allocate new dictionary object 
  6.  
  7.     clear dictionary's table 
  8.  
  9.     set dictionary's number of used slots + dummy slots (ma_fill) to 0 
  10.  
  11.     set dictionary's number of active slots (ma_used) to 0 
  12.  
  13.     set dictionary's mask (ma_value) to dictionary size - 1 = 7 
  14.  
  15.     set dictionary's lookup function to lookdict_string 
  16.  
  17.     return allocated dictionary object  

添加項

添加新的鍵/值對調用的是PyDict_SetItem()函數。函數將使用一個指針指向字典對象和鍵/值對。這一過程中,首先會檢查鍵是否是字符串,然后計算哈希值,如果先前已經計算并緩存了鍵的哈希值,則直接使用緩存的值。接著調用insertdict()函數添加新鍵/值對。如果活動槽和空槽的總數超過數組長度的2/3,則需調整數組的長度。為什么是 2/3 ?這主要是為了保證探測序列能夠以足夠快的速度找到空閑槽。后面我們會介紹調整長度的函數。

  1. arguments: dictionary, key, value 
  2.  
  3. returns: 0 if OK or -1 
  4.  
  5. function PyDict_SetItem: 
  6.  
  7.     if key's hash cached: 
  8.  
  9.         use hash 
  10.  
  11.     else
  12.  
  13.         calculate hash 
  14.  
  15.     call insertdict with dictionary object, key, hash and value 
  16.  
  17.     if key/value pair added successfully and capacity over 2/3: 
  18.  
  19.         call dictresize to resize dictionary's table  

inserdict() 使用搜尋函數 lookdict_string() 來查找空閑槽。這跟查找鍵所用的是同一函數。lookdict_string() 使用哈希值和掩碼計算槽的索引。如果用“索引 = 哈希值&掩碼”的方法未找到鍵,則會用調用先前介紹的循環方法探測,直至找到一個空閑槽。***輪探測,如果未找到匹配的鍵的且探測過程中遇到過啞槽,則返回一個啞槽。這可使優先選擇先前刪除的槽。

現在我們想添加如下的鍵/值對:{‘a’: 1, ‘b’: 2′, ‘z’: 26, ‘y’: 25, ‘c’: 5, ‘x’: 24},那么將會發生如下過程:

分配一個字典結構,內部表的尺寸為8。 

[[191897]] 

以下就是我們目前所得到的:

 

8個槽中的6個已被使用,使用量已經超過了總容量的2/3,因而,dictresize()函數將會被調用,用以分配一個長度更大的數組,同時將舊表中的條目復制到新的表中。

在我們這個例子中,dictresize()函數被調用后,數組長度調整后的長度不小于活動槽數量的 4 倍,即minused = 24 = 4*ma_used。而當活動槽的數量非常大(大于50000)時,調整后長度應不小于活動槽數量的2倍,即2*ma_used。為什么是 4 倍?這主要是為了減少調用調整長度函數的次數,同時能顯著提高稀疏度。

新表的長度應大于 24,計算長度值時會不斷對當前長度值進行升位運算,直到大于 24,最終得到的長度是 32,例如當前長度為 8 ,則計算過程如8 -> 16 -> 32。

這就是長度調整的過程:分配一個長度為 32 的新表,然后用新的掩碼,也就是 31 ,將舊表中的條目插入到新表。最終得到的結果如下:

 

 

刪除項

刪除條目時將調用PyDict_DelItem()函數。刪除時,首先計算鍵的哈希值,然后調用搜詢函數返回到該條目,***該槽被標記為啞槽。

假設我們想要從字典中刪除鍵'c',我們最終將得到如下結果:

 

注意,刪除項目后,即使最終活動槽的數量遠小于總的數量也不會觸發調整數組長度的動作。但是,若刪減后又增加鍵/值對時,由于調整長度的條件判斷基于的是活動槽與啞槽的總數量,因而可能會縮減數組長度。

責任編輯:龐桂玉 來源: Python開發者
相關推薦

2017-05-24 15:50:08

PythonCPython

2021-04-27 08:54:43

ConcurrentH數據結構JDK8

2023-11-24 17:58:03

Python哈希

2010-07-13 10:13:35

Perl內部函數

2021-09-03 09:55:43

架構Yarn內部

2023-11-23 19:30:35

Python編程語言

2017-09-05 08:08:37

asyncio程序多線程

2010-09-25 15:59:54

JVM虛擬機

2021-08-19 16:56:37

Python內存開發

2017-06-13 12:40:47

Python字符串對象

2024-03-12 10:25:14

C#Dictionary編程語言

2024-11-15 06:00:00

Python列表字典

2021-03-26 22:23:13

Python算法底層

2014-04-23 14:40:06

iOS開發KVO內部實現

2021-08-12 15:45:23

Pythonimport模塊

2016-10-20 08:46:17

2015-07-28 10:06:03

C#內部實現剖析

2022-10-26 15:22:31

React組件User組件

2025-05-22 08:15:00

2025-03-20 09:54:47

點贊
收藏

51CTO技術棧公眾號

欧美日韩国产网站| 日韩永久免费视频| 国产精品传媒精东影业在线| 91精品国产综合久久久蜜臀粉嫩 | 国产xxxx视频| 高清不卡亚洲| 亚洲免费观看视频| 国产自产在线视频一区| 欧美高清69hd| 亚洲人成人一区二区三区| 一区二区三区视频观看| 一级黄色片在线免费观看| 天天综合av| 一区二区三区欧美在线观看| 日本免费高清不卡| www黄色在线观看| 久久国产人妖系列| 国内外成人免费激情在线视频网站 | 91香蕉视频黄| 亚洲综合色激情五月| 毛片基地在线观看| 午夜视频一区| 最近2019年手机中文字幕| 国产白嫩美女无套久久| 日韩黄色在线| 在线看日韩精品电影| 久久国产精品视频在线观看| 香蕉视频在线播放| 91香蕉国产在线观看软件| 成人自拍视频网站| 国产人妻精品一区二区三| 肉色丝袜一区二区| 午夜精品久久久久久久99热| 国产传媒免费在线观看| 欧美精品一区二区三区精品| 亚洲韩国欧洲国产日产av| 91欧美一区二区三区| 激情欧美一区二区三区黑长吊| 欧美日韩国产一中文字不卡 | 在线中文字幕-区二区三区四区 | 色播亚洲视频在线观看| 天堂中文在线视频| 成人黄色小视频在线观看| 成人国产在线激情| 亚洲影院一区二区三区| 日韩电影在线一区二区三区| 欧美影院在线播放| 日韩一区二区视频在线| 国产精品久久久久9999高清| 久久人人爽人人爽人人片av高请| 青青青在线免费观看| 国产精品久久久久久久| 国产亚洲欧洲在线| www色com| 日韩伦理视频| 日韩资源在线观看| 极品尤物一区二区| 国产精品88久久久久久| 色婷婷综合久久久久| 激情无码人妻又粗又大| 欧美大片aaaa| 超碰97人人做人人爱少妇| 国产精品视频一区二区在线观看| 日韩一区三区| 久久亚洲春色中文字幕| 黄色一级片在线免费观看| 亚洲欧美综合| 国内精品伊人久久| 国产成人精品777777| 青草国产精品久久久久久| 国产精品视频免费在线观看| 一区二区三区免费在线视频| 国产精品白丝av| 国产精品久久久久久久免费大片 | 久久中文字幕在线视频| 久久久久久久久久久久久女过产乱| 亚洲欧美网站在线观看| 欧美激情2020午夜免费观看| 日本少妇吞精囗交| 快she精品国产999| 成人夜晚看av| 日本精品久久久久| 国产日产欧美精品一区二区三区| 在线一区亚洲| 黄色美女视频在线观看| 色综合久久99| 波多野结衣免费观看| 久久久久97| 一区二区亚洲欧洲国产日韩| 黄色一级片中国| 免费中文字幕日韩欧美| 国产精品视频免费在线观看| www.好吊色| 国产欧美一区二区三区在线看蜜臀| 一区二区三区三区在线| 国产三线在线| 欧美日韩精品一区二区三区| 在线中文字日产幕| 成人激情诱惑| 午夜精品久久久久久久99热浪潮| 日本一区二区三区久久| 国产成人精品三级| 日本在线视频一区| 国产亚av手机在线观看| 欧美三级日韩三级国产三级| 天天躁日日躁狠狠躁av| 999成人精品视频线3| 26uuu亚洲伊人春色| 国产夫妻在线观看| 日本一区二区在线不卡| 天堂…中文在线最新版在线| 日日干夜夜操s8| 偷拍精品精品一区二区三区| 日韩一卡二卡三卡四卡| 日韩女同一区二区三区 | 人体内射精一区二区三区| 日本在线中文字幕一区二区三区| 欧美xxxxxxxxx| 人人艹在线视频| 在线亚洲观看| 官网99热精品| 黄色在线观看网站| 欧美无砖砖区免费| 黄色正能量网站| 亚洲黄色免费| 不卡的av一区| a视频在线免费看| 欧美视频一二三区| 成人午夜福利一区二区| 亚洲精品美女91| 99视频在线| 午夜小视频在线观看| 欧美日韩1区2区| 俄罗斯毛片基地| 久久一区视频| 欧美日韩一区二| 色在线视频观看| 亚洲精品理论电影| 久久草视频在线| 成人av免费在线观看| 欧美中日韩在线| 2020国产精品极品色在线观看| 九色精品免费永久在线| 精品久久在线观看| 亚洲综合视频在线观看| aaaaa黄色片| 99成人超碰| 91在线视频成人| 国产秀色在线www免费观看| 欧美另类久久久品| 亚洲 欧美 变态 另类 综合| 国产主播一区二区| 91精品国产吴梦梦| 日韩一区网站| 久久久久日韩精品久久久男男| 亚洲a视频在线| 亚洲高清免费观看高清完整版在线观看| 女王人厕视频2ⅴk| 红桃视频亚洲| 国产精品99久久久久久久| 波多野结衣中文字幕久久| 欧美videossexotv100| 精品在线视频免费| 久久综合狠狠综合久久综合88| 日韩人妻精品无码一区二区三区| 亚洲女娇小黑人粗硬| 国产激情综合五月久久| 1769在线观看| 日韩一级片在线观看| 国产无码精品一区二区| 久久一区二区三区四区| 欧美特级aaa| 欧美日韩调教| 久久精品国产99精品国产亚洲性色| 日本在线播放一二三区| 亚洲图片在线综合| 一本色道久久综合精品婷婷| 一区二区三区在线视频免费观看| 亚洲美女高潮久久久| 久久都是精品| 中文字幕一区二区中文字幕| av综合网页| 国产成人一区二区三区小说| 日本三级视频在线观看| 精品免费日韩av| 日本欧美www| 一区二区三区精品| 日本一级免费视频| 国内成人自拍视频| 日韩欧美亚洲天堂| 国产电影一区二区在线观看| 激情一区二区三区| 成人免费观看49www在线观看| 亚洲**2019国产| 好操啊在线观看免费视频| 亚洲精品456在线播放狼人| 伊人网综合在线| 亚洲一区二区三区不卡国产欧美| 制服 丝袜 综合 日韩 欧美| 国产精品1区2区3区在线观看| 欧美三级一级片| 欧美 日韩 国产精品免费观看| 久久视频在线观看中文字幕| 国产高清精品二区| 日韩av成人在线观看| 日本片在线观看| 在线日韩欧美视频| 天堂中文资源在线观看| 666欧美在线视频| 久久久久久久久久成人| 亚洲综合男人的天堂| 国产麻豆a毛片| 久久无码av三级| 国产在线观看免费播放| 另类调教123区 | 久久精品国产成人一区二区三区| 日韩国产一级片| 中文字幕亚洲综合久久五月天色无吗'' | 亚洲免费av网站| 57pao国产成人免费| 六月婷婷综合网| 91麻豆精品久久久久蜜臀| 高潮毛片又色又爽免费| 天天色图综合网| 黄色一级免费视频| 亚洲欧洲日韩女同| 国产一二三av| 国产女同性恋一区二区| 公侵犯人妻一区二区三区| 成人免费视频国产在线观看| 九九九久久久久久久| 九九热在线视频观看这里只有精品| 日本美女高潮视频| 久久久久久9| 92看片淫黄大片一级| 亚洲精品1234| 国产不卡一区二区视频| 在线播放亚洲| 欧美久久久久久久久久久久久| 欧美成人高清| 波多野结衣av一区二区全免费观看| 7777久久香蕉成人影院| 国产一二三四五| 91精品一区二区三区综合在线爱 | 激情久久中文字幕| www国产无套内射com| 欧美在线免费一级片| 正在播放国产精品| 天天影视天天精品| 18视频在线观看娇喘| 欧美 日韩 国产精品免费观看| av中文字幕av| 怡红院精品视频在线观看极品| 成人av在线播放观看| 国产综合精品一区| 亚洲国产精品无码观看久久| 一区二区动漫| caopor在线视频| 久久精品免费观看| 天天操天天干天天做| 国产一区二区三区久久久| 超碰人人cao| aaa亚洲精品一二三区| av在线网站观看| 国产喂奶挤奶一区二区三区| 国产三级在线观看完整版| 国产精品二区一区二区aⅴ污介绍| 911国产在线| 一区二区三区四区av| 天天做天天爱夜夜爽| 欧美日韩国产综合一区二区三区| 99久久精品国产一区二区成人| 精品国产91洋老外米糕| 日本私人网站在线观看| 中文日韩在线视频| 国产精品一卡二卡三卡| 午夜精品三级视频福利| 激情开心成人网| 91久久国产婷婷一区二区| 国产精品视屏| 日本一区二区在线| 综合一区二区三区| 国产午夜福利在线播放| 久久精品国产免费| 美女搡bbb又爽又猛又黄www| 国产欧美一区二区精品久导航| 丝袜 亚洲 另类 欧美 重口| 五月婷婷另类国产| 91麻豆国产视频| 日韩av资源在线播放| 调教视频免费在线观看| 欧美—级高清免费播放| 91成人在线| 精品国产乱码久久久久| 国产精品毛片久久| 成人免费毛片网| 国产一区二区三区高清播放| 欧美 变态 另类 人妖| 中文字幕视频一区| 国产性生活视频| 精品日韩欧美在线| 91在线看片| 欧美做受高潮1| 91久久偷偷做嫩草影院电| 色999日韩自偷自拍美女| 999亚洲国产精| 精品人妻人人做人人爽夜夜爽| 国产清纯白嫩初高生在线观看91 | 欧美区高清在线| 在线成人激情| 亚洲欧美久久久久| 久久综合一区二区| 久草视频免费播放| 欧美日韩成人一区| 国产粉嫩一区二区三区在线观看| 91精品国产91久久久久久不卡 | 日韩成人免费电影| 精品熟女一区二区三区| 亚洲另类在线视频| 在线黄色av网站| 亚洲色图35p| 麻豆免费在线| 国产精品二区三区| 欧美成人日韩| 91网址在线观看精品| 中文字幕制服丝袜成人av| 精人妻无码一区二区三区| 亚洲精品国精品久久99热| 牛牛精品在线| 99久热re在线精品996热视频| 亚洲一本二本| 日韩一区二区三区不卡视频| 久久精品免视看| 亚洲欧美偷拍一区| 亚洲美女喷白浆| 亚洲黄色免费av| 欧美美乳视频网站在线观看| 中文一区二区| 给我免费观看片在线电影的| 亚洲电影激情视频网站| 国产 日韩 欧美 精品| 色综合天天综合网国产成人网 | 妺妺窝人体色www婷婷| 制服丝袜亚洲网站| 国产三区在线观看| 亚洲综合在线小说| 亚洲网址在线| 菠萝菠萝蜜网站| 一本一道综合狠狠老| 国产精品无码2021在线观看| 国产精品美女久久久免费 | 91麻豆成人久久精品二区三区| 国产精品自拍视频一区| 亚洲精品成人网| 综合毛片免费视频| 日本一区二区久久精品| 日韩有码一区二区三区| 欧美老女人性生活视频| 欧美日韩国产中文| a级影片在线| 国产精品免费在线| 亚洲一区区二区| 欧美一区二区三区粗大| 91精品国产综合久久精品麻豆 | 国产高清视频免费最新在线| 国产精品男人的天堂| 国产精品97| 北京富婆泄欲对白| 色综合久久天天综合网| av国产在线观看| av一区二区三区在线观看| 亚洲精品视频啊美女在线直播| 在线免费观看黄色小视频| 欧美亚洲动漫精品| 超碰免费在线播放| 精品视频一区在线| 美女精品一区二区| 欧美精品久久久久性色| 亚洲免费中文字幕| 久久人体av| 青青草精品视频在线| 欧美国产日韩一二三区| www.黄色一片| 日韩免费在线播放| 亚洲二区三区不卡| 欧美丰满少妇人妻精品| 欧美剧情片在线观看| 92久久精品| 色呦呦网站入口| 91色.com| 国产xxxxxx| 欧洲亚洲免费在线| 中文字幕午夜精品一区二区三区| 播金莲一级淫片aaaaaaa| 7777精品伊人久久久大香线蕉最新版| 国产剧情av在线播放| 在线观看欧美亚洲| 91麻豆6部合集magnet| www.久久久久久| 国产精品久久久久av|