1. 程式人生 > >set去重應用

set去重應用

一次循環 存在 一次 lib 準備 urn 自己 同時 return

1.其中涉及__hash__與__eq__這兩個內置方法.

2.列如: 要求用類生成多個對象,其中姓名和性別相同的對象可認為是同一個人,用set原理做去重

class People:

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

self.name=name

self.age=age

self.sex=sex

def __hash__(self): 對象找自帶的hash算法,set的算法是算全部,現在改為了算自定義的部分

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

return res 返回的hash值和原數據類型做綁定再加入集合中,如需取出則給出原數據類型

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__的運算標準修改成了對象中的姓名+性別的形式組成的字符串,所以運算時

只會運算這個字符串,所以成了姓名和性別相同的去重,而不管其余部分是否相同.

set去重應用