set去重应用

1.其中涉及__hash__与__eq__这两个内置方法.算法

2.列如: 要求用类生成多个对象,其中姓名和性别相同的对象可认为是同一我的,用set原理作去重app

class People:函数

    def __init__(self,name,age,sex):spa

        self.name=name对象

        self.age=age内存

        self.sex=sex字符串

    def __hash__(self):         对象找自带的hash算法,set的算法是算所有,如今改成了算自定义的部分hash

        res=hash(self.name+self.sex)it

        return  res                   返回的hash值和原数据类型作绑定再加入集合中,如需取出则给出原数据类型class

    def __eq__(self,other):   发现重复的hash值自动触发,并把重复的这两个拿出来作对比

        if self.name+self.sex==other.name+other.sex:   set对比的是所有,如今对比的是自定义的部分

           return  True              如返回True则抛弃,Flase则从新计算并加入.

people_lis=[]

for  i  in  range(1,200):

    people_lis.append(People(‘张三’, i ,’男’))

for  i  in  range(1,200):

    people_lis.append(People(‘李四’, i ,’女’))

for  i  in  people_lis:

print(i.__dict__)

我的理解:首先,这个东西要先搞明白集合的运行原理,或者说去重原理吧. set(可迭代对象).

1.先说集合的原理吧.集合自带有相似于for循环的机制,会把放入其中的可迭代对象中的元素依次拿出来用

 自带的__hash__hsah(元素)的算法,而后在内存中把其保存为:元素名+指向的形式(指向什么呢?指向的就

 是存放hash值的格子),当循环到某个元素的时候发现其Hash出来的值对应的格子已经有东西了,这时

 候会生成:(当前元素==已存在的hash值对应的元素名)这样的一个形式来触发自带的__eq__方法,若是这

 两个比较后的值为True,则抛弃当前元素不予处理.若是为Flase,则再次进行一系列运算,从而保证获得一个

 不一样的值再予以保存.

2.再来讲说这个列子中的变化. 首先给了set一个可迭代的列表,set会利用自带的循环机制挨个拿出来列表

   中的每一个元素,而后用自带的hash算法准备给元素进行运算,此时必然是hash(元素)这么的一个形式,可是这

   种形式在此列中还有另外一层含义,那就是调用对象的hash函数的意思,对象本类此时就具备这个函数,因而

   就走了对象本身的了,然而本身的hash算法是通过修改的,就是提取对象中某一部分来进行hsah运算,不作

 对象总体的运算,运算完成后会在内存中保存成(完整对象名+修改算法后的指向).当下一次循环来的对象

 提取相同部分作完运算,如发现该指向已然有东西了,set准备再次用==来对比当前对象和已存对象值是

 否相同时( 此时形式为:当前对象==已存对象).这个形式的另外一层意义就起做用了,这是要调set__eq__

 方法,对象本类就有该方法,因而走的就是本类的__eq__方法,可是本类的这个东西也是通过修改的,修改的

 是对比对象中某一段的值是否相同,相同则抛弃不予处理,不一样则存起来.

 因自带的__hash__ __eq__的运算标准修改为了对象中的姓名+性别的形式组成的字符串,因此运算时

 只会运算这个字符串,因此成了姓名和性别相同的去重,而无论其他部分是否相同.

相关文章
相关标签/搜索