Python 哈希表與可哈希對象
===================
哈希表(散清單)
哈希是從 Hash 音譯過來的,哈希表(hashtable),也叫做散清單。
哈希表是鍵值對的無序集合,其每個鍵都是唯一的,核心算法是通過索引去查找值,Python 中的字典符合哈希表結構,字典中每個鍵對應一個值,
my_dict={"key1":"value1","key2":"value2"}
。
哈希是使用算法将任意大小的資料映射到固定長度輸出的過程,該輸出就是哈希值。
雜湊演算法可以建立高性能的資料結構,該結構可以快速存儲和通路大量資料,哈希值通過哈希函數計算。
哈希函數,本質上是鍵到值的映射關系;
哈希表本質上就是一個數組,存儲的是經過哈希函數運算之後得到的值;
哈希值是唯一辨別資料的固定長度的數值。
這些都屬于概念層面的知識,初期了解即可,後面随着應用會逐漸掌握。
可哈希與不可哈希
這部分在 官方文檔 說的比較繞,簡單說一下的結論(也是大家共識的),一個對象(Python 中萬物皆對象)在生命周期内,保持不變,就是可哈希的(hashable)。
還有一個更簡單的證明辦法,在 Python 中能插入
set
集合的元素是可哈希的,例如下述代碼:
my_set = set()
test = [1, 3.14, 'hello', (2, 3), {'key': 1}, [1, 2], {3,6}]
my_set.add(test[0])
my_set.add(test[1])
my_set.add(test[2])
my_set.add(test[3])
# my_set.add(test[4])
# my_set.add(test[5])
# my_set.add(test[6])
複制
測試之後得到的結論是:
- 可以被哈希的資料結構:
、int
、float
、str
;tuple
- 不可以被哈希的資料結構:
、dict
、list
。set
加上之前滾雪球學到的知識,可以了解到,可以被哈希的資料類型都是不可變的,而不可以被哈希的資料類型是可變的,有點繞,稍微停頓一下,多讀兩遍即可。
可哈希的對象通常用作和
字典的鍵
的成員,因為這些資料結構在内部使用哈希值。
集合
最終結論:
可哈希
≈
不可變
。
Python hash() 函數
hash
函數用于擷取一個對象的哈希值,文法結果為
hash(object)
,傳回值是對象的哈希值, 哈希值是整數。
使用方式非常簡單:
print(hash('test'))
print(hash(1))
# 注意下面使用不可哈希對象會出現錯誤
# hash([1,2,3])
複制
hashlib 子產品
hashlib
提供了常見的摘要算法,具體如下:
md5()、sha1()、sha224()、sha256()、sha384()、sha512()、blake2b()、blake2s()、sha3_224()、sha3_256()、sha3_384()、 sha3_512()、 shake_128()、shake_256()
使用
dir(hashlib)
即可擷取上述所有可用方法。
MD5
是最常見的摘要算法,生成結果是固定的 16 位元組,通常用一個 32 位的 16 進制字元串表示,示例代碼如下:
import hashlib
# MD5算法
md5 = hashlib.md5()
data = "hello world"
md5.update(data.encode('utf-8'))
# 計算 hash 值,拿到加密字元串
print(md5.hexdigest())
複制
SHA1 算法更安全,它的結果是 20 位元組長度,通常用一個 40 位的 16 進制字元串表示。而比 SHA1 更安全的算法是 SHA256 和 SHA512 等,不過越安全的算法越慢,并且摘要長度更長。
這篇部落格的總結
本篇部落格為大家說明了 Python 的哈希表概念和可哈希對象,對于初學階段是有幫助的。
深入研究下去,你應該嘗試自己手寫雜湊演算法與可哈希對象,再學習一段時間吧,希望本文對你有所幫助。