當前位置:ag真人国际官网-ag旗舰厅官方网站 » 編程語言 » python實現哈希表

python實現哈希表-ag真人国际官网

發布時間: 2024-07-14 20:21:42

a. python數據結構與演算法-哈希map的實現及原理

1-collections.mutablemapping

1.1 概念:這是什麼?

大家可能想知道這一串英文是什麼意思?其實只需要了解在collections庫當中有一個非常重要的抽象基類mutablemappin

g,專門用於實現map的一個非常有價值的工具。後邊我們會用到它。

2-我們的map基類


2.1 實現這個類

這個基類其實也就是確定了鍵值對的屬性,並且存儲了基本的比較方法。它的對象就是一個鍵值對咯。這個很好理解。有點類似object的感覺。

3-通過map基類實現的無序映射

給大家看一個上邊的例子,這個例子來源於網路,自己改了改,能用,更加詳細而已,湊合看.

4-python哈希表的實現的基類

4.1 咱有話直說:上才(代)藝(碼)

如果還不知道哈希表概念的同xio,請參考 python進階之數據結構與演算法–中級-哈希表(小白piao分享) 。廢話不多說,咱們擼代碼:

ok了,基本的哈希表就實現了,其實仔細想想很容易,但是自己要能實現還是要理解哈希表的本質哦,外加一定量的練習才可以熟練掌握,練習的目的就是為了熟練而已。

5-分離鏈表實現的具體哈希map類

說明:這玩意只是一種降低沖突的手段,上一節提過,降低沖突最好的地方是發生在元組進入桶的時候,所以想必大家猜到了,接下來的分離鏈表也就是為了self._bucket_xxxxxxx系列方法做准備。這里之所以在上邊使用@abstractmethod就是為了繼承實現,目的可以實現多種將沖突的哈希表。分離鏈表的概念上一節也有的。
「見碼入面」(借鑒:見字如面這個電視節目,有興趣可以看看,還不錯的):

6-用線性探測處理沖突的哈希map類

這種方式的好處不需要再去藉助其他額外的賦值結構來表示桶。結構更加簡單。不會再像上一種方法還要讓桶是一個unsortedtablemap的對象。
代碼如下:

b. python dict 實現原理 2019-04-17

dict對象是python中一個原始的數據類型,按照鍵值對的方式存儲,中文名為字典,其通過鍵名查找對應的值有很高的效率,時間復雜度在常數級別o(1)。python dict的底層是依靠哈希表(hash table)進行實現的,使用開放地址法解決沖突。所以其查找的時間復雜度會是o(1),why?

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

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

創建一個數組,數組下標是索引號,數組中的值是要獲得的數據,這樣只需要o(1)的時間復雜度就可以完成操作,但是擴展性不強,有以下兩個方面的考慮:
-1- 新添加的元素超出數組索引范圍,這就需要重新申請數組進行遷移操作。
-2- 假設一種極端的情況:只存在兩個元素,索引號分別是1和100000000001,按照先前的設計思路,會浪費很大的存儲空間。
會不會存在一個方法,為已有的索引創建新的索引,通過壓縮位數,讓新索引可以和原有的大范圍的稀疏索引進行一一對應,新索引所需要的存儲空間要大大減小,這就是哈希思想。

上面的例子中哈希函數的設計很隨意,但是從這個例子中我們也可以得到信息:
哈希函數就是一個映射,因此哈希函數的設定很靈活,只要使得任何關鍵字由此所得的哈希函數值都落在表長允許的范圍之內即可;
因為新的索引對舊的索引進行了空間上的壓縮,所以不可能所有的輸入都只對應唯一一個輸出,也就是哈希函數式有可能發生沖突的,哈希函數不可能做成一對一的映射關系,其本質是一個多對一的映射。

直接定址法:很容易理解,key=value c; 這個「c」是常量。value c其實就是一個簡單的哈希函數。
除法取余法: 很容易理解, key=value%c;解釋同上。
數字分析法:這種蠻有意思,比如有一組value1=112233,value2=112633,value3=119033,針對這樣的數我們分析數中間兩個數比較波動,其他數不變。那麼我們取key的值就可以是key1=22,key2=26,key3=90。
平方取中法。此處忽略,見名識意。
折疊法:這種蠻有意思,比如value=135790,要求key是2位數的散列值。那麼我們將value變為13 57 90=160,然後去掉高位「1」,此時key=60,哈哈,這就是他們的哈希關系,這樣做的目的就是key與每一位value都相關,來做到「散列地址」盡可能分散的目地。

當兩個不同的數據元素的哈希值相同時,就會發生沖突。解決沖突常用的手法有2種:
開放地址法:
如果兩個數據元素的哈希值相同,則在哈希表中為後插入的數據元素另外選擇一個表項。當程序查找哈希表時,如果沒有在第一個對應的哈希表項中找到符合查找要求的數據元素,程序就會繼續往後查找,直到找到一個符合查找要求的數據元素,或者遇到一個空的表項。
鏈接法:
將哈希值相同的數據元素存放在一個鏈表中,在查找哈希表的過程中,當查找到這個鏈表時,必須採用線性查找方法。

python的dict採用了哈希表,最低能在 o(1)時間內完成搜索,在發生哈希沖突的時候採用的是開放定址法。java的hashmap也是採用了哈希表實現,但是在發生哈希沖突的時候採用的是鏈接法。

c. python字典鍵值對的添加和遍歷

添加鍵值對
首先定義一個空字典
>>> dic={}
直接對字典中不存在的key進行賦值來添加
>>> dic['name']='zhangsan'
>>> dic
{'name': 'zhangsan'}
如果key或value都是變數也可以用這種方法
>>> key='age'
>>> value=30
>>> dic[key]=value
>>> dic
{'age': 30. 'name': 'zhangsan'}
這里可以看到字典中的數據並不是按先後順序排列的,如果有興趣,可以搜一搜數據結構中的——哈希表
從python3.7開始,字典按照插入順序,實現了有序。修改一個已存在的key的值,不影響順序,如果刪了一個key後再添加該key,該key會被添加至末尾。標准json庫的mp(s)/load(s)也是有序的
還可以用字典的setdefault方法
>>> dic.setdefault('sex','male')
'male'
>>> key='id'
>>> value='001'
>>> dic.setdefault(key,value)
'001'
>>> dic
{'id': '001', 'age': 30. 'name': 'zhangsan', 'sex': 'male'}

d. python 字典為什麼這么快

因為字典是通過鍵來索引的,關聯到相對的值,理論上他的查詢復雜度是o(1)。
哈希表(也叫散列表),根據關鍵值對(key-value)而直接進行訪問的數據備羨結構。它通過把key和value映射到表中一個位置來訪問記錄,這種查詢速度非常快,更新也快。而這個映射函數叫做哈希函數,存放值的數組叫做哈希表。 哈希函數的實唯肢現方式決定了哈希表的指滾世搜索效率。

e. 利用python進行數據分析筆記:3.1數據結構

元組是一種固定長度、不可變的python對象序列。創建元組最簡單的辦法是用逗號分隔序列值:

tuple 函數將任意序列或迭代器轉換為元組:

中括弧 [] 可以獲取元組的元素, python中序列索引從0開始

元組一旦創建,各個位置上的對象是無法被修改的,如果元組的一個對象是可變的,例如列表,你可以在它內部進行修改:

可以使用 號連接元組來生成更長的元組:

元組乘以整數,則會和列表一樣,生成含有多份拷貝的元組:

將元組型的表達式賦值給變數,python會對等號右邊的值進行拆包:

拆包的一個常用場景就是遍歷元組或列表組成的序列:

*rest 用於在函數調用時獲取任意長度的位置參數列表:

count 用於計量某個數值在元組中出現的次數:

列表的長度可變,內容可以修改。可以使用 [] 或者 list 類型函數來定義列表:

append 方法將元素添加到列表尾部:

insert 方法可以將元素插入到指定列表位置:
插入位置范圍在0到列表長度之間

pop 是 insert 的反操作,將特定位置的元素移除並返回:

remove 方法會定位第一個符合要求的值並移除它:

in 關鍵字可以檢查一個值是否在列表中;
not in 表示不在:

號可以連接兩個列表:

extend 方法可以向該列表添加多個元素:

使用 extend 將元素添加到已經存在的列表是更好的方式,比 快。

sort 方法可以對列表進行排序:

key 可以傳遞一個用於生成排序值的函數,例如通過字元串的長度進行排序:

bisect.bisect 找到元素應當被插入的位置,返回位置信息
bisect.insort 將元素插入到已排序列表的相應位置保持序列排序

bisect 模塊的函數並不會檢查列表是否已經排序,因此對未排序列表使用bisect不會報錯,但是可能導致不正確結果

切片符號可以對大多數序列類型選取子集,基本形式是 [start:stop]
起始位置start索引包含,結束位置stop索引不包含

切片還可以將序列賦值給變數:

start和stop可以省略,默認傳入起始位置或結束位置,負索引可以從序列尾部進行索引:

步進值 step 可以在第二個冒號後面使用, 意思是每隔多少個數取一個值:

對列表或元組進行翻轉時,一種很聰明的用法時向步進值傳值-1:

dict(字典)可能是python內建數據結構中最重要的,它更為常用的名字是 哈希表 或者 關聯數組
字典是鍵值對集合,其中鍵和值都是python對象。
{} 是創建字典的一種方式,字典中用逗號將鍵值對分隔:

你可以訪問、插入或設置字典中的元素,:

in 檢查字典是否含有一個鍵:

del 或 pop 方法刪除值, pop 方法會在刪除的同時返回被刪的值,並刪除鍵:

update 方法將兩個字典合並:
update方法改變了字典元素位置,對於字典中已經存在的鍵,如果傳給update方法的數據也含有相同的鍵,則它的值將會被覆蓋。

字典的值可以是任何python對象,但鍵必須是不可變的對象,比如標量類型(整數、浮點數、字元串)或元組(且元組內對象也必須是不可變對象)。
通過 hash 函數可以檢查一個對象是否可以哈希化(即是否可以用作字典的鍵):

集合是一種無序且元素唯一的容器。

set 函數或者是用字面值集與大括弧,創建集合:

union 方法或 | 二元操作符獲得兩個集合的聯合即兩個集合中不同元素的並集:

intersection 方法或 & 操作符獲得交集即兩個集合中同時包含的元素:

常用的集合方法列表:

和字典類似,集合的元素必須是不可變的。如果想要包含列表型的元素,必須先轉換為元組:

f. python dict用法

dic= {key1 : value1, key2 : value2 }

字典也被稱作關聯數組或哈希表。下面是幾種常見的字典屬性:

1、dict.clear()

clear() 用於清空字典中所有元素(鍵-值對),對一個字典執行 clear() 方法之後,該字典就會變成一個空字典。

2、dict.()

() 用於返回一個字典的淺拷貝。

3、dict.fromkeys()

fromkeys() 使用給定的多個鍵創建一個新字典,值默認都是 none,也可以傳入一個參數作為默認的值。

4、dict.get()

get() 用於返回指定鍵的值,也就是根據鍵來獲取值,在鍵不存在的情況下,返回 none,也可以指定返回值。

5、dict.items()

items() 獲取字典中的所有鍵-值對,一般情況下可以將結果轉化為列表再進行後續處理。

6、dict.keys()

keys() 返回一個字典所有的鍵。

g. python dict怎麼實現的

python中dict對象是表明了其是一個原始的python數據類型,按照鍵值對的方式存儲,其中文名字翻譯為字典,顧名思義其通過鍵名查找對應的值會有很高的效率,時間復雜度在常數級別o(1).dict底層實現(推薦學習:python視頻教程)
在python2中,dict的底層是依靠哈希表(hash table)進行實現的,使用開放地址法解決沖突.
所以其查找的時間復雜度會是o(1).
dict的操作實現原理(包括插入、刪除、以及緩沖池等)
首先介紹:pydictobject對象的元素搜索策略:
有兩種搜索策略,分別是lookdict和lookdict_string,lookdict_string就是lookdict在對於pystringobject進行搜索時的特殊形式,那麼通用的搜索策略lookdict的主要邏輯是:
(1)對第一個entry的查找:
a)根據hash值獲得entry的索引
b)若entry處於unused態,則搜索結束;若entry所指向的key與搜索的key相同,則搜索成功
c)若當前entry處於mmy態,則設置freeslot(這里的freeslot是可以返回作為下一個立即可用的地址來存儲entry)
d)檢查active態的entry,若其key所指向的值與搜索的值相同,則搜索成功
(2)對剩餘的探測鏈中的元素的遍歷查找:
a)根據所採用的探測函數,獲得探測鏈上的下一個待檢查的entry
b)檢查到一個unused態的entry,表明搜索失敗:
如果freeslot不為空,則返回freeslot;否則返回unused態的entry
c)檢查entry的key與所搜索的key的引用是否相同,相同則搜索成功,返回entry
d)檢查entry的key與所搜索的key的值是否相同,相同則搜索成功,返回entry
e)遍歷過程中,發現mmy態的entry,且freeslot未設置,則設置freeslot
接下來是:pydictobject對象的元素插入與刪除的策略:
需要首先用到搜索策略,搜索成功,則直接將值進行替換,搜索失敗,返回unused態或mmy態的entry,設置key、value和hash值,並且根據目前插入的元素情況進行ma_table的大小的調整(調整的依據就是裝載率,根據是否大於2/3來進行調整);刪除也是類似,先計算hash值,然後搜索相應的entry,搜索成功,刪除entry中維護的元素,將entry從active態修改為mmy態

在pydictobject的實現過程中,會用到緩沖池,在pydictobject對象被銷毀的時候,才開始接納被緩沖的pydictobject對象,定義的緩沖池可接納的對象數量是80個,創建新pydictobject對象的時候,如果緩沖池中有,則可以直接從緩沖池中取出使用
更多python相關技術文章,請訪問python教程欄目進行學習!以上就是小編分享的關於python dict怎麼實現的的詳細內容希望對大家有所幫助,更多有關python教程請關注環球青藤其它相關文章!

h. 這段c語言代碼如何轉換成python語言(關於哈希表)

將以上 c 語言代碼轉換為 python 語言可能需要對哈希表和其他數據結構進行重新實現。但是可以提供一個類似的實現方式
def search_hash(hash_table, name):
collisions = 0 # to keep track of number of collisions
index = hash_function(name)
while hash_table[index] is not none and hash_table[index]['name'] != name:
collisions = 1
index = collision_resolution(index)
if hash_table[index] is not none:
print("search successful! number of collisions:", collisions)
print("name: ", hash_table[index]['name'])
print("id: ", hash_table[index]['id'])
print("phone: ", hash_table[index]['phone'])
else:
print("search unsuccessful.")
這個例子使用了字典來存儲聯系人的信息,其中 'name','id' 和 'phone' 是字典的鍵。hash_function() 和 collision_resolution() 函數可以用 python 中的內置函數來實現,或者自己實現。
注意,這只是一種類似的實現方式,並不能完全替代原來的代碼,還需要根據實際需求進行修改。
另外,在 python 中可以使用字典或字典組成的列表來存肆指儲哈希表,可以使用字典中的 get() 方法或者列表中的 in 關鍵字來查找一個元素是否在字典或列表中,如果要實現類似 c 語言中的沖突解決方式明察,可以在字典中使用鏈表或線性探測法來實現激雹茄。
這里只是給出了一種可能的實現方式,具體實現還需要根據具體需求進行調整。

i. python 如何找出兩個list中的相同元素

這個問題有多種解法,最常見的是brute-force 也叫暴力枚舉法,也就是把兩個list當中的每個元素都取出來進行兩兩比較,直到找到相同元素。設第一個數組的長度為n,第二個數胡兆組的長度為m,則時間復雜度為o(n*m),空間復雜度為o(1)
但是個問題陵穗常見的解決方法是哈希表。在python當中有dictionary這種數據類型,其實是一個哈希表。運用這種數據類型,可以迅速檢索到想要的元素。但這種方法需要存儲一組元素,所以時間復雜度為o(n),空間復雜度為o(m)。
以下是程序:
def find_same_element(l1, l2):
dist = {}
for i in l1:
dist[i] = 1
for i in l2:
if dist.get(i) > none:
return i
return none

以下是檢驗
l1 = [1, 2, '34', 34, 5]
l2 = [4, 7, 8]
print find_same_element(l1, l2)
應當輸出none
l1 = [1, 2, '34', 34, 5]
l2 = [4, 7, 8,5]
print find_same_element(l1, l2)
應當輸出5

這個函數只能找尺做卜到一個共同元素,如果兩個list有多個相同元素則只能輸出中間的一個。

這個問題常見於面試題,屬於最簡單的面試題目。需要給面試官說明的是,
第一,哈希表可以快速檢索元素,
第二,python有獨特的數據類型,
第三,多個共同元素的情況需要面試官告知如何處理,
第四,注意沒有共同元素的時候的輸出(程序中為none但面試官希望你能提出這個問題)

熱點內容
matlab命令窗口和新建腳本 發布:2024-07-17 15:51:26 瀏覽:374
建ftp文件夾 發布:2024-07-17 15:51:26 瀏覽:954
魔獸撿物腳本 發布:2024-07-17 15:27:56 瀏覽:129
開發ip伺服器 發布:2024-07-17 15:24:42 瀏覽:387
安卓系統視頻製作哪個好用 發布:2024-07-17 15:10:47 瀏覽:210
androidapk結構 發布:2024-07-17 15:10:43 瀏覽:945
c語言指針的例子 發布:2024-07-17 15:08:01 瀏覽:768
linuxzcat 發布:2024-07-17 15:02:09 瀏覽:901
賓士編程嗎 發布:2024-07-17 14:57:08 瀏覽:853
硬碟加密硬體 發布:2024-07-17 14:51:05 瀏覽:836
网站地图