最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python?哈希表的實現(xiàn)——字典詳解

 更新時間:2023年11月25日 09:18:49   作者:edisonfish  
這篇文章主要介紹了Python?哈希表的實現(xiàn)——字典,那么今天我們就來看看哈希表的原理以及如何實現(xiàn)一個簡易版的?Python?哈希表,需要的朋友可以參考下

接觸過 Python 的小伙伴應該對【字典】這一數(shù)據(jù)類型都了解吧

雖然 Python 沒有顯式名稱為“哈希表”的內(nèi)置數(shù)據(jù)結構,但是字典是哈希表實現(xiàn)的數(shù)據(jù)結構

在 Python 中,字典的鍵(key)被哈希,哈希值決定了鍵對應的值(value)在字典底層數(shù)據(jù)存儲中的位置

那么今天我們就來看看哈希表的原理以及如何實現(xiàn)一個簡易版的 Python 哈希表

ps:文中提到的 Python 指的是 CPyhton 實現(xiàn)

何為哈希表?

哈希表(hash table)通常是基于“鍵-值對”存儲數(shù)據(jù)的數(shù)據(jù)結構

哈希表的鍵(key)通過哈希函數(shù)轉換為哈希值(hash value),這個哈希值決定了數(shù)據(jù)在數(shù)組中的位置。這種設計使得數(shù)據(jù)檢索變得非常快

舉個例子,下面有一組鍵值對數(shù)據(jù),其中歌手姓名是 key,歌名是 value

+------------------------------+
|   Key        |   Value       |
+------------------------------+
| Kanye        | Come to life  |
| XXXtentacion | Moonlight     |
| J.cole       | All My Life   |
| Lil wanye    | Mona Lisa     |
| Juice WRLD   | Come & Go     |
+------------------------------+

如果我們想要將這些鍵值對存儲在哈希表中,首先需要將鍵的值轉換成哈希表的數(shù)組的索引,這時候就需要用到哈希函數(shù)了

哈希函數(shù)是哈希表實現(xiàn)的主要關鍵,它能夠處理鍵然后返回存放數(shù)據(jù)的哈希表中對應的索引

一個好的哈希函數(shù)能夠在數(shù)組中均勻地分布鍵,盡量避免哈希沖突(兩個鍵返回了相同的索引)

哈希函數(shù)是如何處理鍵的,這里我們創(chuàng)建一個簡易的哈希函數(shù)來模擬一下(實際上哈希函數(shù)要比這復雜得多)

def simple_hash(key, size):
    return ord(key[0]) % size

這個簡易版哈希函數(shù)將歌手名(即 key)首字母的 ASCII 值與哈希表大小取余,得出來的值就是歌名(value)在哈希表中的索引

那這個簡易版哈希函數(shù)有什么問題呢?聰明的你一眼就看出來了:容易出現(xiàn)碰撞。因為不同的鍵的首字母有可能是一樣的,就意味著返回的索引也是一樣的

例如我們假設哈希表的大小為 10 ,我們以上面的歌手名作為鍵然后執(zhí)行 simple_hash(key, 10) 得到索引

可以看到,由于Juice WRLDJ.cole 的首字母都一樣,哈希函數(shù)返回了相同的索引,這里就發(fā)生了哈希碰撞

雖然幾乎不可能完全避免任何大量數(shù)據(jù)的碰撞,但一個好的哈希函數(shù)加上一個適當大小的哈希表將減少碰撞的機會

當出現(xiàn)哈希碰撞時,可以使用不同的方法(例如開放尋址法)來解決碰撞

應該設計健壯的哈希函數(shù)來盡量避免哈希碰撞

我們再來看其他的鍵,Kanye 通過 simple_hash() 函數(shù)返回 index 5,這意味著我們可以在索引 5 (哈希表的第六個元素)上找到 其鍵 Kanye 和值Come to life

哈希表優(yōu)點

在哈希表中,是根據(jù)哈希值(即索引)來尋找數(shù)據(jù),所以可以快速定位到數(shù)據(jù)在哈希表中的位置,使得檢索、插入和刪除操作具有常數(shù)時間復雜度 O(1) 的性能

與其他數(shù)據(jù)結構相比,哈希表因其效率而脫穎而出

不但如此,哈希表可以存儲不同類型的鍵值對,還可以動態(tài)調(diào)整自身大小

Python 中的哈希表實現(xiàn)

在 Python 中有一個內(nèi)置的數(shù)據(jù)結構,它實現(xiàn)了哈希表的功能,稱為字典

Python 字典(dictionary,dict)是一種無序的、可變的集合(collections),它的元素以 “鍵值對(key-value)”的形式存儲

字典中的 key 是唯一且不可變的,這意味著它們一旦設置就無法更改

my_dict = {"Kanye": "Come to life", "XXXtentacion": "Moonlight", "J.cole": "All My Life"}

在底層,Python 的字典以哈希表的形式運行,當我們創(chuàng)建字典并添加鍵值對時,Python 會將哈希函數(shù)作用于鍵,從而生成哈希值,接著哈希值決定對應的值將存儲在內(nèi)存的哪個位置中

所以當你想要檢索值時,Python 就會對鍵進行哈希,從而快速引導 Python 找到值的存儲位置,而無需考慮字典的大小

my_dict = {}
my_dict["Kanye"] = "Come to life" # 哈希函數(shù)決定了 Come to life" 在內(nèi)存中的位置
print(my_dict["Alice"]) # "Come to life" 

可以看到,我們通過方括號[key]來訪問鍵對應的值,如果鍵不存在,則會報錯

print(my_dict["Kanye"])  # "Come to life" 
# Raises KeyError: "Drake"
print(my_dict["Drake"])

為了避免該報錯,我們可以使用字典內(nèi)置的 get() 方法,如果鍵不存在則返回默認值

print(my_dict.get('Drake', "Unknown")) # Unknown

在 python 中實現(xiàn)哈希表

首先我們定義一個 HashTable 類,表示一個哈希表數(shù)據(jù)結構

class HashTable:
    def __init__(self, size):
        self.size = size
        self.table = [None]*size
    def _hash(self, key):
        return ord(key[0]) % self.size

在構造函數(shù) __init__() 中:

  • size 表示哈希表的大小
  • table是一個長度為 size 的數(shù)組,被用作哈希表的存儲結構。初始化時,數(shù)組的所有元素都被設為 None,表示哈希表初始時不含任何數(shù)據(jù)

在內(nèi)部函數(shù) _hash() 中,用于計算給定 key 的哈希值。它采用給定鍵 key 的第一個字符的 ASCII 值,并使用取余運算 % 將其映射到哈希表的索引范圍內(nèi),以便確定鍵在哈希表中的存儲位置。

然后我們接著在 HashTable 類中添加對鍵值對的增刪查方法

class HashTable:
    def __init__(self, size):
        self.size = size
        self.table = [None]*size
    def _hash(self, key):
        return ord(key[0]) % self.size
    def set(self, key, value):
        hash_index = self._hash(key)
        self.table[hash_index] = (key, value)
    def get(self, key):
        hash_index = self._hash(key)
        if self.table[hash_index] is not None:
            return self.table[hash_index][1]
        raise KeyError(f'Key {key} not found')
    def remove(self, key):
        hash_index = self._hash(key)
        if self.table[hash_index] is not None:
            self.table[hash_index] = None
        else:
            raise KeyError(f'Key {key} not found')

其中,set() 方法將鍵值對添加到表中,而 get() 該方法則通過其鍵檢索值。該 remove() 方法從哈希表中刪除鍵值對

現(xiàn)在,我們可以創(chuàng)建一個哈希表并使用它來存儲和檢索數(shù)據(jù):

# 創(chuàng)建哈希表
hash_table = HashTable(10)
# 添加鍵值對
hash_table.set('Kanye', 'Come to life')
hash_table.set('XXXtentacion', 'Moonlight')
# 獲取值
print(hash_table.get('XXXtentacion'))  # Outputs: 'Moonlight'
# 刪除鍵值對
hash_table.remove('XXXtentacion')
# 報錯: KeyError: 'Key XXXtentacion not found'
print(hash_table.get('XXXtentacion'))

前面我們提到過,哈希碰撞是使用哈希表時不可避免的一部分,既然 Python 字典是哈希表的實現(xiàn),所以也需要相應的方法來處理哈希碰撞

在 Python 的哈希表實現(xiàn)中,為了避免哈希沖突,通常會使用開放尋址法的變體之一,稱為“線性探測”(Linear Probing)

當在字典中發(fā)生哈希沖突時,Python 會使用線性探測,即從哈希沖突的位置開始,依次往后查找下一個可用的插槽(空槽),直到找到一個空的插槽來存儲要插入的鍵值對。

這種方法簡單直接,可以減少哈希沖突的次數(shù)。但是,它可能會導致“聚集”(Clustering)問題,即一旦哈希表中形成了一片連續(xù)的已被占用的位置,新元素可能會被迫放入這片區(qū)域,導致哈希表性能下降

為了緩解聚集問題,假若當哈希表中存放的鍵值對超過哈希表長度的三分之二時(即裝載率超過66%時),哈希表會自動擴容

最后總結一下:

  • 在哈希表中,是根據(jù)哈希值(即索引)來尋找數(shù)據(jù),所以可以快速定位到數(shù)據(jù)在哈希表中的位置
  • Python 的字典以哈希表的形式運行,當我們創(chuàng)建字典并添加鍵值對時,Python 會將哈希函數(shù)作用于鍵,從而生成哈希值,接著哈希值決定對應的值將存儲在內(nèi)存的哪個位置中
  • Python 通常會使用線性探測法來解決哈希沖突問題

到此這篇關于Python 哈希表的實現(xiàn)——字典的文章就介紹到這了,更多相關Python 哈希表字典內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Jupyter Notebook安裝及使用方法解析

    Jupyter Notebook安裝及使用方法解析

    這篇文章主要介紹了Jupyter Notebook安裝及使用方法解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-11-11
  • python3獲取當前文件的上一級目錄實例

    python3獲取當前文件的上一級目錄實例

    下面小編就為大家分享一篇python3獲取當前文件的上一級目錄實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-04-04
  • Django中QuerySet查詢優(yōu)化之prefetch_related詳解

    Django中QuerySet查詢優(yōu)化之prefetch_related詳解

    prefetch_related()和select_related()的設計目的很相似,都是為了減少SQL查詢的數(shù)量,但是實現(xiàn)的方式不一樣,下面這篇文章主要給大家介紹了關于Django中QuerySet查詢優(yōu)化之prefetch_related的相關資料,需要的朋友可以參考下
    2022-11-11
  • python3中sorted函數(shù)里cmp參數(shù)改變詳解

    python3中sorted函數(shù)里cmp參數(shù)改變詳解

    在本篇文章里小編給大家整理的是關于python3中sorted函數(shù)里關于cmp這一參數(shù)的改變相關內(nèi)容,需要的朋友們可以學習下。
    2020-03-03
  • 對django中foreignkey的簡單使用詳解

    對django中foreignkey的簡單使用詳解

    今天小編就為大家分享一篇對django中foreignkey的簡單使用詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • Python使用os模塊和fileinput模塊來操作文件目錄

    Python使用os模塊和fileinput模塊來操作文件目錄

    這篇文章主要介紹了Python編程中使用os模塊和fileinput模塊來操作文件的方法,包括獲取路徑和創(chuàng)建愛你刪除目錄等基本操作的例子,需要的朋友可以參考下
    2016-01-01
  • python 圖片驗證碼代碼

    python 圖片驗證碼代碼

    在網(wǎng)絡應用中,驗證碼常常作為一個必備的手段,用來避免機器人惡意注冊,保證坐在瀏覽器前的是一個人。
    2008-12-12
  • Pycharm 設置自定義背景顏色的圖文教程

    Pycharm 設置自定義背景顏色的圖文教程

    今天小編就為大家分享一篇Pycharm 設置自定義背景顏色的圖文教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-05-05
  • python定時執(zhí)行指定函數(shù)的方法

    python定時執(zhí)行指定函數(shù)的方法

    這篇文章主要介紹了python定時執(zhí)行指定函數(shù)的方法,涉及Python中sleep方法延時執(zhí)行的相關使用技巧,需要的朋友可以參考下
    2015-05-05
  • Python實現(xiàn)分割文件及合并文件的方法

    Python實現(xiàn)分割文件及合并文件的方法

    這篇文章主要介紹了Python實現(xiàn)分割文件及合并文件的方法,涉及Python針對文件的分割與合并操作相關技巧,通過自定義函數(shù)split與join實現(xiàn)了文件的分割與合并操作,需要的朋友可以參考下
    2015-07-07

最新評論

务川| 天门市| 永吉县| 安陆市| 平武县| 铜陵市| 贡觉县| 五常市| 西贡区| 客服| 绍兴县| 元阳县| 平和县| 江北区| 宿迁市| 固始县| 明星| 封开县| 阜城县| 庆阳市| 伊金霍洛旗| 睢宁县| 台州市| 和政县| 仪征市| 安丘市| 湘潭县| 都昌县| 荔浦县| 内黄县| 南郑县| 家居| 新平| 康保县| 陆河县| 广州市| 东辽县| 腾冲县| 洛浦县| 长乐市| 奉化市|