python的set去重原理 Set去重原理

2021-10-19 03:25:57 字數 3015 閱讀 6050

在上篇文章《雜湊值和可變性hash value and mutability》最後說到set去重問題,所以這篇主要是通過實踐來研究一下set去重背後的故事,當然也是參考了網上一些資料得到了一些啟發,感謝那些陌生的喜歡分享的博友們。

set的簡單應用

利用set中元素的唯一性,我們可以對list去重

list1 = [1,2,3,1,2,3]

print(set(list1))

# output:

set去重的原理

set中元素的hash值不一樣

class person:

def __init__(self, name, identityid):

self.name = name

self.identityid = identityid

def __hash__(self):

print("%s call hash method"%self.name)

return hash(id(self))

def __eq__(self, other):

print("%s call eq method"%self.name)

if self.__dict__ == other.__dict__:

return true

else:

return false

p1 = person('p1', 123456789)

p2 = person('p2', 123456789)

print("p1 id: %s"%hex(id(p1)))

print("p2 id: %s"%hex(id(p2)))

list_test = [p1,p2]

print(set(list_test))

可以看出set呼叫了元素的hash方法,p1和p2的hash返回不同,就認為是不重複的元素,所以不去重

#output:

p1 id: 0x209563fabe0

p2 id: 0x209563fa910

p1 call hash method

p2 call hash method

set中元素的hash返回值是一樣的

class person:

def __init__(self, instance, name, identityid):

self.instance = instance

self.name = name

self.identityid = identityid

def __hash__(self):

print("%s call hash method"%self.instance)

return hash(self.identityid)

def __eq__(self, other):

print(f" call eq method: equal to ")

if self.name == other.name:

return true

else:

return false

p1 = person('p1','kelly', 123456789)

p2 = person('p2','xia', 123456789)

p3 = person('p3','peter', 111111111)

p4 = person('p4','kelly', 123456789)

p5 = person('p5','kelly.xia', 123456789)

print("p1 id: %s"%hex(id(p1)))

print("p2 id: %s"%hex(id(p2)))

print("p3 id: %s"%hex(id(p3)))

print("p4 id: %s"%hex(id(p4)))

print("p5 id: %s"%hex(id(p5)))

print(f"p1==p4:")

list_test = [p1,p2,p3,p4,p5]

print(set(list_test))

p1,p2,p3,p4,p5,通過id來看是指向不同的引用的,p1和p2的hash返回值相同,所以再呼叫p1的eq方法,eq返回是false的,所以認為p1和p2是不重複的。而p1和p4,hash返回值是一樣的,再使用者p1的eq方法,返回是ture,所以認為p1和p4是重複的,將除去p4.最後的p5,跟p1,p2的hash返回值都是一樣的,所以再分別呼叫p1和p2的eq方法,因為eq訪求返回都為false,所以認為p5分別和p1,p2是不重複的。

#output:

p1 id: 0x209564e1fd0

p2 id: 0x209564e1070

p3 id: 0x209564e1ac0

p4 id: 0x209564e1430

p5 id: 0x209564e1c40

p1 call eq method: equal to p4

p1==p4:true

p1 call hash method

p2 call hash method

p1 call eq method: equal to p2

p3 call hash method

p4 call hash method

p1 call eq method: equal to p4

p5 call hash method

p1 call eq method: equal to p5

p2 call eq method: equal to p5

結論由以上得出結論:set的去重是通過兩個函式__hash__和__eq__結合實現的。當兩個物件的雜湊值不相同時,就認為這兩個物件是不同的; 當兩個物件的雜湊值一樣時,呼叫__eq__方法,當返回值為true時認為這兩個物件是重複的,應該去除乙個。返回false時,認為這兩個物件不是重複的,所以不去重。

應用利用set去重特性,我們擴充套件思維應用到許多需要去重的場景中去,關鍵就是override超類object的__hash__和__eq__方法。

set 去重原理

眾所周知,set 是 python 中的 天然去重因子 對一串資料如 lyst 1,1,2,4,4 我們常常 set 一下,也就是 set lyst 達到去重目的。那麼,set 是如何去重的呢?為了貼合實際的開發需求,我們常需要自定義資料結構。拿通用示例 student 來說。class stude...

陣列去重 Set

常見的陣列去重方法大多考慮遍歷 indexof,例如 var arr1 1 2,3 4,5 6,6 6 function unique arr return newarr unique arr1 1,2,3,4,5,6 但是es6引入了新的資料結構set,可以直接實現陣列去重 甚至也可以用於字串去重...

set 的方法以及set 去重

set 迴圈的時候,key 和value的值是一樣的 建立 let setarr new set 增 setarr.add 1,2,3,1 2 3 console.log setarr.size 6 刪 set.clear 減 set.delete 1 查 set.has 1 true 1 set沒...