python dict底層實現_dict實現原理和哈希表

dict底層實現

在Python中,字典是依靠散列表或說哈希表(Hash Table)進行實現的,使用開放地址法解決沖突。所以其查找的時間復雜度會是O(1),下文會具體講解哈希表的工作原理和解決沖突時的具體方法。

也就是說,字典也是一個數組,但數組的索引是鍵經過哈希函數處理后得到的散列值。哈希函數的目的是使鍵均勻地分布在數組中,并且可以在內存中以O(1)的時間復雜度進行尋址,從而實現快速查找和修改。哈希表中哈希函數的設計困難在于將數據均勻分布在哈希表中,從而盡量減少哈希碰撞和沖突。由于不同的鍵可能具有相同的哈希值,即可能出現沖突,高級的哈希函數能夠使沖突數目最小化。

通常情況下建立哈希表的具體過程如下:

數據添加:把key通過哈希函數轉換成一個整型數字,然后就將該數字對數組長度進行取余,取余結果就當作數組的下標,將value存儲在以該數字為下標的數組空間里。

數據查詢:再次使用哈希函數將key轉換為對應的數組下標,并定位到數組的位置獲取value

哈希函數就是一個映射,因此哈希函數的設定很靈活,只要使得任何關鍵字由此所得的哈希函數值都落在表長允許的范圍之內即可。本質上看哈希函數不可能做成一個一對一的映射關系,其本質是一個多對一的映射,這也就引出了下面一個概念–哈希沖突或者說哈希碰撞。哈希碰撞是不可避免的,但是一個好的哈希函數的設計需要盡量避免哈希碰撞。

Python2中使用使用開放地址法解決沖突。

CPython使用偽隨機探測(pseudo-random probing)的散列表(hash table)作為字典的底層數據結構。由于這個實現細節,只有可哈希的對象才能作為字典的鍵

哈希表

哈希表是key-value類型的數據結構,通過關鍵碼值直接進行訪問。通過散列函數進行鍵和數組的下標映射從而決定該鍵值應該放在哪個位置,哈希表可以理解為一個鍵值需要按一定規則存放的數組,而哈希函數就是這個規則。此處提出幾個專業名詞后面會一一進行介紹。

哈希函數

裝填因子

沖突

1.哈希表產生的原因假設我們存在一個簡單的鍵值對結構,鍵-員工號,值-是否在崗。現在需要這樣一個功能,輸入員工號,返回該員工是否在崗,理想的方法是創建一個長度為Max(員工號)的數組,數組下標就是員工號,數組中的值用0和1對是否在崗進行區分,這樣只需要O(1)的時間復雜度就可以完成操作,但是擴展性不強,存在以下問題。

假設新進員工的員工號比Max(員工號)還要大,這就需要重新申請數組進行遷移操作。

假設一種極端的情況,存在兩個員工,員工號分別是1和100000000001,這樣子的話按照先前的設計思路,是會浪費很大的存儲空間的。

上面兩點,第一點是因為數組的固定申請大小的屬性所決定,而第二點就是引入哈希表的原因,會不會存在一個方法,讓一個大員工號變小而而且沒有標記,哈希函數便產生,假設此處的哈希規則是除3取模,則員工1得到的哈希值是1,員工100000000001得到的哈希值是

這樣的話按照設計思路,只需要一個大小為2的數組便可以覆蓋了,這就是哈希思想。

算法中時間和空間是不能兼得的,哈希表就是一種用合理的時間消耗去減少大量空間消耗的操作,這取決于具體的功能要求。

2. 哈希函數

上面的例子中哈希函數的設計很隨意,但是從這個例子中我們也可以得到信息:

哈希函數就是一個映射,因此哈希函數的設定很靈活,只要使得任何關鍵字由此所得的哈希函數值都落在表長允許的范圍之內即可;

并不是所有的輸入都只對應唯一一個輸出,也就是哈希函數不可能做成一個一對一的映射關系,其本質是一個多對一的映射,這也就引出了下面一個概念–沖突。

3. 沖突

只要不是一對一的映射關系,沖突就必然會發生,還是上面的極端例子,這時新加了一個員工號為2的員工,先不考慮我們的數組大小已經定為2了,按照之前的哈希函數,工號為2的員工哈希值也是2,這與100000000001的員工一樣了,這就是一個沖突,針對不同的解決思路,提出三個不同的解決方法。

4.沖突解決方法

4.1 開放地址

開放地址的意思是除了哈希函數得出的地址可用,當出現沖突的時候其他的地址也一樣可用,常見的開放地址思想的方法有線性探測再散列,二次探測再散列,這些方法都是在第一選擇被占用的情況下的解決方法。

4.2 再哈希法

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

4.3 鏈地址法

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

4.4公共溢出區

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

5.裝填因子α

一般情況下,處理沖突方法相同的哈希表,其平均查找長度依賴于哈希表的裝填因子。哈希表的裝填因子定義為表中填入的記錄數和哈希表長度的壁紙,也就是標志著哈希表的裝滿程度。直觀看來,α越小,發生沖突的可能性就越小,反之越大。一般0.75比較合適,涉及數學推導

原文:https://blog.csdn.net/shouting3901/article/details/80468735

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/542433.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/542433.shtml
英文地址,請注明出處:http://en.pswp.cn/news/542433.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

網際控制報文協議icmp_網絡中的ICMP(Internet控制消息協議)

網際控制報文協議icmpICMP(Internet控制消息協議)簡介 (Introduction to ICMP (Internet Control Message Protocol)) IP (Internet Protocol) is a network layer protocol. The responsibility of delivering data (Logical Addressing) to any network is done by the IP (I…

談色

最近很苦惱,像是到了男人的生理期,或者說是類似動物的發情期,見到露長腿的女人總喜歡看。 其實我是并不喜歡這樣盯著看,或許是男人的本色,十個男人九個色的本性,總是會不自覺的去偷看,更有甚者還…

linux系統怎樣寫單片機程序,單片機知識是Linux驅動開發的基礎之一以及如何學單片機...

這是arm裸機1期加強版第1課第2、3節課程的wiki文字版。為什么沒前途也要學習單片機?因為它是個很好的入口。學習單片機可以讓我們拋開復雜的軟件結構,先掌握硬件操作,如:看原理圖、芯片手冊、寫程序操作寄存器等。在上一節視頻里&…

python教程循環語句_Python教程:關于Python 循環語句

Python 循環語句本章節將向大家介紹Python的循環語句,程序在一般情況下是按順序執行的。編程語言提供了各種控制結構,允許更復雜的執行路徑。循環語句允許我們執行一個語句或語句組多次,下面是在大多數編程語言中的循環語句的一般形式&#x…

math.pow int_Java Math類static int min(int i1,int i2)與示例

math.pow int數學類靜態int min(int i1,int i2) (Math Class static int min(int i1 , int i2) ) This method is available in java.lang package. 此方法在java.lang包中可用。 This method is used to return the minimum one of both the given arguments or in…

bat 批處理 常用命令和亂碼問題

為什么80%的碼農都做不了架構師?>>> rem echo off ECHO OFF XCOPY E:\test.bat D:\ IF ERRORLEVEL 1 ECHO 文件拷貝Failure IF ERRORLEVEL 0 ECHO 文件拷貝Success :start set /p first"1記事本,2遠程:" if %first% LEQ 2 (IF %first% …

SuperMap iServer發布的ArcGIS REST 地圖服務如何通過ArcGIS API加載

作者:yx 文章目錄 一、發布服務二、代碼加載三、結果展示 一、發布服務 SuperMap iServer支持將地圖發布為ArcGIS REST地圖服務,您可以在發布服務時直接勾選ArcGIS REST地圖服務,如下圖所示: 也可以在已發布的地圖服務中&#x…

c語言中的運算符及其含義_按位運算符及其在C語言中與Example一起使用

c語言中的運算符及其含義1)&(按位與) (1) & (bitwise AND)) It does AND on every bit of two numbers. The result of AND is 1 only if both bits are 1. 它對兩個數字的每一位進行“與”運算。 僅當兩個位均為1時,AND的結果才為1。 Example: 例&…

能上網的Linux系統,那一款linux能上網

zhoushao12 于 2009-02-24 19:13:07發表:linux日常使用中,最重要的就是網絡(本人覺得)特別時ubuntu .但是現在電信偏偏搞什么賬號加密要用互聯星空軟件才可以撥號,更可惡的是這X軟件只有Windws版的!! 使得在linux下撥號上網變得十分麻煩!在網上找了很久終于找到解決方法!!下面拿…

李洪強經典面試題37

1.寫一個NSString類的實現 (id)initWithCString:(c*****t char *)nullTerminatedCString encoding:(NSStringEncoding)encoding; (id) stringWithCString: (c*****t char*)nullTerminatedCString encoding: (NSStringEncoding)encoding { NSString *obj; obj [self al…

new file會創建文件嗎_Rust 文件系統處理之文件讀寫 Rust 實踐指南

Rust 中,文件讀寫處理簡單而高效。代碼也很緊湊,容易閱讀。我們從讀取文件的字符串行、避免讀取寫入同一文件、使用內存映射隨機訪問文件這三個文件處理中的典型案例來了解一下。文件處理場景大家都很熟悉,因此閑言少敘,直接看代碼…

python 打印文件名_在Python中打印文件名,關閉狀態和文件模式

python 打印文件名Prerequisite: Opening, closing a file/open(), close() functions in Python 先決條件: 在Python中打開,關閉文件/ open(),close()函數 1)文件名(file_object.name) (1) File name (file_object.name)) To get the file …

linux搭建直播步驟,Linux 下 nginx + rtmp 搭建直播服務

簡單粗暴直接上步驟吧:注 : 以下示例使用的是nginx(版本1.15.3) rtmp(版本1.2.1)下載nginx和rtmp模塊下載nginx解壓? tar xvf nginx-1.15.3.tar.gz下載nginx rtmp模塊解壓? tar xvf v1.2.1進入nginx目錄? cd nginx-1.15.3執行:#--add-module 指向rtmp模塊目錄,ad…

【Maven學習筆記(二)】Maven的安裝與配置

為什么80%的碼農都做不了架構師&#xff1f;>>> 1、默認本地倉庫路徑 C:\Users\97449\.m2\repository 2、修改本地倉庫路徑 打開D:\apache-maven\conf\settings.xml <?xml version"1.0" encoding"UTF-8"?><!-- Licensed to the Apa…

npm 全局安裝vuecli報錯_cnn explainer本地使用--被npm坑慘

最近在知乎上面看到&#xff0c;看到一個cnn解釋器&#xff0c;把每個步揍都很清楚的展示了出來&#xff0c;我想自己搞來玩玩。第一次使用npm&#xff0c;很多地方不會&#xff0c;第一步&#xff1a;先在網頁上下載下來cnn_explainer&#xff0c;然后解壓在沒有中文路徑的文件…

Python程序從給定的N個數字中找到最大倍數

Here, we will be framing code for finding the maximum multiple of a number x from a given set of a number (set of 5 numbers in this program). 在這里&#xff0c;我們將使用成幀代碼&#xff0c; 從給定的一組數字(此程序中的5個數字組成的集合)中找到x的最大倍數 。…

ubuntu linux本地源,如何制作UbuntuLinux操作系統的本地源?

最簡單制作本地源的方法&#xff1a;在packs文件夾中有如下兩種類型的包&#xff1a;一種是。deb包(全部的依賴包和軟件包)&#xff0c;另一種是Packages。gz著重介紹一下第二個類型的包&#xff1a;在這個包中包含了必需的軟件包列表和依賴信息。這個包是后生成的&#xff0c;…

openmpi安裝_Intel Parallel Studio XE 2019安裝設置

1.Intel Parallel Studio XE 2019簡介Intel Parallel Studio XE 是Intel在單獨一款軟件開發套件中整合了英特爾公司業界領先的 C/C 和 Fortran 編譯器、性能和MPI并行庫、錯誤檢查、代碼健壯和性能分析的工具&#xff0c;有助于大幅提升應用程序性能&#xff0c;同時提高代碼質…

Python | 在列表中指定索引處添加元素的程序

Given a list and we have to add an element at specified index in Python. 給定一個列表&#xff0c;我們必須在Python中的指定索引處添加一個元素。 list.appened() Method is used to append/add an element at the end of the list. But, if we want to add an element …