class Foo():
pass
obj1 = Foo()
obj2 = Foo()
print(hash(obj1)) # 内存地址 136382060082
print(hash(obj1)) # 内存地址 136382060082
print(hash(obj1)) # 内存地址 136382060082
print(hash(obj1)) # 内存地址 136382060082
print(hash(obj1)) # 175716959794 同样的值第二次执行时,hash地址变了
每次执行hash值都会变化
在一次执行的过程中对同一个值的hash结果总是不变的
set的去重机制就是hash算法,
set中没个值传进去,首先给每个值赋予一个hash值,然后如果值相等hash值必然一样,再对比里面的值是否相等
如果相等,给第第二个值再hash一下,给个新的hash地址给它,相比与用for循环去重节省时间和内存,for循环每个
值都比一下是否相等。如果数据量很大的话,用的时间非常多。
为什么dict寻址快,因为dict的key是可hash的,每个key都有一个hash值,如果key很长,比如一个对象,他对应的
就是个hash值,通过hash值直接可以找到这个hash值对应的地址中的值。
例
class Staff: # 定义一个员工的类
def __init__(self, name, age, sex, dep):
self.name = name
self.age = age
self.sex = sex
self.dep = dep
def __hash__(self): # 定义__hash__内置方法
return hash(self.name + self.sex) # 返回的是名字和性别的hash值的和,由于对象是不可hash的,又想用hash的方法找出名字和性别一样的员工,name和sex是字符串,可hash
def __eq__(self, other):
if self.name == other.name and self.sex == other.sex:
return True
#
name_lst = ['yuan', 'laura', 'wendy', 'sinila']
obj_lst = []
for i in range(100):
name = name_lst[i % 4] # 列表里面4个值,1到100除4,取余数,
obj = Staff(name, i, 'male', 'python')
obj_lst.append(obj)
print(obj_lst)
ret = set(obj_lst) # 集合的运行机制中这个hash()方法和==方法,这两个方法自动触发类中的__hash__方法,然后再触发__eq__方法
print(ret)
for i in ret:
print(i.name, i.age)
>>>
sinila 3
wendy 2
laura 1
yuan 0
内置函数进阶 __hash__, 以及集合运行机制
猜你喜欢
转载自blog.csdn.net/weixin_42233629/article/details/82355229
今日推荐
周排行