在复习可变对象和不可变对象时,学到了这个内容
1. 前置知识:哈希是什么
哈希(Hashing)是一种将任意大小的数据转换成固定大小的数据的过程。这种转换通过哈希函数实现,它接收输入(或“消息”),并返回一个通常具有固定长度的字符串,这个字符串被称为哈希值或哈希码。哈希的主要用途包括数据的快速查找、数据完整性校验、以及安全应用中的加密技术。
哈希的关键特点是:
- 效率高:哈希函数设计为能够快速处理大量数据。
- 确定性:对于同一输入总是产生相同的输出。
- 随机分布:哈希值应均匀且随机分布,减少冲突。
- 不可逆性:理想的哈希函数使得从哈希值恢复原始输入极其困难。
2. 可哈希和不可哈希对象的定义
2.1可哈希
可哈希对象是指其生命周期内具有不变的哈希值的对象。这些对象可以作为字典的键或者集合的元素。整数、浮点数、字符串和元组都是可哈希的。
整数的哈希值
x = 10
print(hash(x)) # 输出:10的哈希值
用内置的hash()函数来获取一个整数的哈希值。
2.2 不可哈希
不可哈希对象是指内容可以更改的对象,因此哈希值也可能会变。列表和字典是典型的不可哈希对象。
列表的不可哈希性
my_list = [1, 2, 3]
try:
print(hash(my_list))
except TypeError as e:
print(e) # 输出错误信息,指出列表是不可哈希的
由于列表是可变的,Python不允许对其进行哈希。所以尝试哈希列表将抛出一个TypeError。
3. 对象的哈希方法
3.1 自定义对象的哈希方法
可哈希对象需要实现__hash__()
方法,该方法返回对象的哈希值。如果对象是可变的,则应返回None,表示对象不可哈希。
class Person:
def __init__(self, name):
self.name = name
def __hash__(self):
return hash(self.name) # 基于名字的哈希值
person = Person('Alice')
print(hash(person)) # 输出:Alice的哈希值
定义了一个Person类,重写__hash__()
方法使其实例可哈希。哈希函数基于人的名字来计算哈希值,根据对象的某个不变属性来提供一个一致的哈希值。
3.2 可哈希性与等价性
如果两个对象的哈希值相同,它们首先被视为可能相等,然后通过__eq__()
方法进行进一步的比较来确定是否真的相等。
实现等价性
class Product:
def __init__(self, id, name):
self.id = id
self.name = name
def __hash__(self):
return hash(self.id)
def __eq__(self, other):
return self.id == other.id
product1 = Product(1, 'Apple')
product2 = Product(1, 'Apple')
print(hash(product1) == hash(product2)) # 输出:True
print(product1 == product2) # 输出:True
Product类通过id属性来定义其哈希方法和等价性检测。只要两个产品的id相同,就被认为是相等的,这说明了在自定义类中如何同时实现__hash__()和__eq__()方法来保证对象可以被正确地用于字典键或集合元素。
3.3 哈希值的用途
哈希值用于快速比较对象是否相同,是字典和集合高效性的关键。
字典中使用哈希值
my_dict = {person: 'Engineer'}
print(my_dict[person]) # 输出:'Engineer'
只有可哈希对象才可以作为字典的键
推荐
推荐我的相关专栏: