欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

關(guān)于Python字典的底層實現(xiàn)原理

 更新時間:2023年02月10日 08:41:17   作者:Generalzy  
這篇文章主要介紹了關(guān)于Python字典的底層實現(xiàn)原理,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

字典是否是有序

在Python3.6之前,字典是無序的,但是Python3.7+,字典是有序的。

在3.6中,字典有序是一個implementation detail,在3.7才正式成為語言特性,因此3.6中無法確保100%有序。

字典的查詢、添加、刪除的時間復雜度

字典的查詢、添加、刪除的平均時間復雜度都是O(1),相比列表與元祖,性能更優(yōu)。

字典的實現(xiàn)原理

Python3.6之前的無序字典

字典底層是維護一張哈希表,可以把哈希表看成一個列表,哈希表中的每一個元素又存儲了哈希值(hash)、鍵(key)、值(value)3個元素。

enteies = [
    ['--', '--', '--'],
    [hash, key, value],
    ['--', '--', '--'],
    ['--', '--', '--'],
    [hash, key, value],
]

帶入具體的數(shù)值來介紹

# 給字典添加一個值,key為hello,value為word
# my_dict['hello'] = 'word'

# hash表初始如下
enteies = [
    ['--', '--', '--'],
    ['--', '--', '--'],
    ['--', '--', '--'],
    ['--', '--', '--'],
    ['--', '--', '--'],
]

hash_value = hash('hello')  # 假設值為 12343543 

index = hash_value & ( len(enteies) - 1)  # 假設index值計算后等于3

# 下面會將值存在enteies中
enteies = [
    ['--', '--', '--'],
    ['--', '--', '--'],
    ['--', '--', '--'],
    [12343543, 'hello', 'word'],  # index=3
    ['--', '--', '--'],
]

# 繼續(xù)向字典中添加值
# my_dict['color'] = 'green'

hash_value = hash('color')  # 假設值為 同樣為12343543
index = hash_value & ( len(enteies) - 1)  # 假設index值計算后同樣等于3

# 下面會將值存在enteies中
enteies = [
    ['--', '--', '--'],
    ['--', '--', '--'],
    ['--', '--', '--'],
    [12343543, 'hello', 'word'],  # 由于index=3的位置已經(jīng)被占用,且key不一樣,所以判定為hash沖突,繼續(xù)向下尋找
    [12343543, 'color', 'green'],  # 找到空余位置,則保存
]

enteies表是稀疏的,隨著我們插入的值不同,enteies表會越來越稀疏(enteies也是一個會動態(tài)擴展長度的,每一此擴展長度,都會重新計算所有key的hash值),所以新的字典實現(xiàn)就隨之出現(xiàn)。

Python3.7+后的新的實現(xiàn)方式

Python3.7+帶入數(shù)據(jù)演示

# 給字典添加一個值,key為hello,value為word
# my_dict['hello'] = 'word'

# 假設是一個空列表,hash表初始如下
indices = [None, None, None, None, None, None]
enteies = []

hash_value = hash('hello')  # 假設值為 12343543
index = hash_value & ( len(indices) - 1)  # 假設index值計算后等于3

# 會找到indices的index為3的位置
indices = [None, None, None, 0, None, None]
# 此時enteies會插入第一個元素
enteies = [
    [12343543, 'hello', 'word']
]

# 我們繼續(xù)向字典中添加值
my_dict['haimeimei'] = 'lihua'

hash_value = hash('haimeimei')  # 假設值為 34323545
index = hash_value & ( len(indices) - 1)  # 假設index值計算后等于 0

# 會找到indices的index為0的位置
indices = [1, None, None, 0, None, None]
# 此時enteies會插入第一個元素
enteies = [
    [12343543, 'hello', 'word'],
    [34323545, 'haimeimei', 'lihua']
]

查詢字典

# 下面是一個字典與字典的存儲
more_dict = {'name': '張三', 'sex': '男', 'age': 10, 'birth': '2019-01-01'}

# 數(shù)據(jù)實際存儲
indices = [None, 2, None, 0, None, None, 1, None, 3]
enteies = [
    [34353243, 'name', '張三'],
    [34354545, 'sex', '男'],
    [23343199, 'age', 10],
    [00956542, 'birth', '2019-01-01'],
]

print(more_dict['age'])  # 當我們執(zhí)行這句時

hash_value = hash('age')  # 假設值為 23343199
index = hash_value & ( len(indices) - 1)  # index = 1

entey_index = indices[1]  # 數(shù)據(jù)在enteies的位置是2
value = enteies[entey_index]  # 所以找到值為 enteies[2]

時間復雜度

字典的平均時間復雜度是O(1),因為字典是通過哈希算法來實現(xiàn)的,哈希算法不可避免的問題就是hash沖突,Python字典發(fā)生哈希沖突時,會向下尋找空余位置,直到找到位置。

如果在計算key的hash值時,如果一直找不到空余位置,則字典的時間復雜度就變成了O(n)了。

常見的哈希沖突解決方法

1 開放尋址法(open addressing)

開放尋址法中,所有的元素都存放在散列表里,當產(chǎn)生哈希沖突時,通過一個探測函數(shù)計算出下一個候選位置,如果下一個獲選位置還是有沖突,那么不斷通過探測函數(shù)往下找,直到找個一個空槽來存放待插入元素。

2 再哈希法

這個方法是按順序規(guī)定多個哈希函數(shù),每次查詢的時候按順序調(diào)用哈希函數(shù),調(diào)用到第一個為空的時候返回不存在,調(diào)用到此鍵的時候返回其值。

3 鏈地址法

將所有關(guān)鍵字哈希值相同的記錄都存在同一線性鏈表中,這樣不需要占用其他的哈希地址,相同的哈希值在一條鏈表上,按順序遍歷就可以找到。

4 公共溢出區(qū)

其基本思想是:所有關(guān)鍵字和基本表中關(guān)鍵字為相同哈希值的記錄,不管他們由哈希函數(shù)得到的哈希地址是什么,一旦發(fā)生沖突,都填入溢出表。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Python中urllib+urllib2+cookielib模塊編寫爬蟲實戰(zhàn)

    Python中urllib+urllib2+cookielib模塊編寫爬蟲實戰(zhàn)

    這篇文章主要介紹了Python的urllib+urllib2+cookielib模塊編寫爬蟲實戰(zhàn),文中給出了抓取豆瓣同城和登陸圖書館查詢圖書歸還的爬取例子,需要的朋友可以參考下
    2016-01-01
  • python繪制風場方向和大小quiver問題

    python繪制風場方向和大小quiver問題

    這篇文章主要介紹了python繪制風場方向和大小quiver問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • 推薦下python/ironpython:從入門到精通

    推薦下python/ironpython:從入門到精通

    推薦下python/ironpython:從入門到精通...
    2007-10-10
  • Python使用分布式鎖的代碼演示示例

    Python使用分布式鎖的代碼演示示例

    這篇文章主要介紹了Python使用分布式鎖的代碼演示,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • Python使用base64模塊進行二進制數(shù)據(jù)編碼詳解

    Python使用base64模塊進行二進制數(shù)據(jù)編碼詳解

    這篇文章主要介紹了Python使用base64模塊進行二進制數(shù)據(jù)編碼詳解,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • python中賦值語句的特點和形式

    python中賦值語句的特點和形式

    這篇文章主要介紹了python中賦值語句的特點和形式,文中介紹了多目標賦值的共享引用問題,多目標賦值其實是多個目標對同一個內(nèi)存空間的引用,這里要分兩種情況,當被引用對象是不可變對象時則不存在問題,感興趣的朋友跟隨小編一起看看吧
    2023-12-12
  • python 常用日期處理-- datetime 模塊的使用

    python 常用日期處理-- datetime 模塊的使用

    這篇文章主要介紹了python 如何對日期進行處理,幫助大家更好的理解和學習python,感興趣的朋友可以了解下
    2020-09-09
  • Pycharm安裝第三方庫、安裝位置以及鏡像設置方法詳解

    Pycharm安裝第三方庫、安裝位置以及鏡像設置方法詳解

    對于Python開發(fā)用戶來講,安裝第三方庫是家常便飯,下面這篇文章主要給大家介紹了關(guān)于Pycharm安裝第三方庫、安裝位置以及鏡像設置方法的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-05-05
  • Pandas-DataFrame知識點匯總

    Pandas-DataFrame知識點匯總

    這篇文章主要介紹了Pandas-DataFrame知識點匯總,DataFrame是一種表格型數(shù)據(jù)結(jié)構(gòu),它含有一組有序的列,每列可以是不同的值,下面我們一起進入文章了解更多詳細內(nèi)容吧,需要的小伙伴也可以參考一下
    2022-03-03
  • 詳解Python如何循環(huán)遍歷Numpy中的Array

    詳解Python如何循環(huán)遍歷Numpy中的Array

    Numpy是Python中常見的數(shù)據(jù)處理庫,是數(shù)據(jù)科學中經(jīng)常使用的庫。在本文中,我們將學習如何迭代遍歷訪問矩陣中的元素,需要的可以參考一下
    2022-04-04

最新評論