python?set()去重的底層原理及實(shí)例
set是什么?
數(shù)學(xué)上,把set稱做由不同的元素組成的集合,集合(set)的成員通常被稱做集合元素(set elements)。Python把這個(gè)概念引入到它的集合類型對(duì)象里。集合對(duì)象是一組無序排列的可哈希的值。集合關(guān)系測(cè)試和union、intersection等操作符在Python里也同樣如我們所預(yù)想地那樣工作。
set特點(diǎn)
集合的元素有三個(gè)特征:
1.確定性:集合中的元素必須是確定的;
2.互異性:集合中的元素互不相同,如:集合A={1,a},則a不能等于1);
3.無序性:集合中的元素沒有先后之分,如:{3,4,5}和{3,5,4}算作同一個(gè)集合。
python中集合(set)是一個(gè)無序不重復(fù)元素的集,基本功能包括關(guān)系測(cè)試和消除重復(fù)元素,還可以計(jì)算交集、差集、并集等,它與列表(list)的行為類似,區(qū)別在于set不同包括重復(fù)的值,而且set元素是無序的。
在python中可以用大括號(hào) {} 創(chuàng)建集合。注意:如果要?jiǎng)?chuàng)建或初始化一個(gè)空集合,你必須用 set() 而不是 {} 。因?yàn)楹笳遻} 作為創(chuàng)建一個(gè)空的字典,以后我們會(huì)介紹字典這種數(shù)據(jù)結(jié)構(gòu)。
一、set去重簡單實(shí)例
ls = [1,2,3,1,2] print(set(ls))

我們知道對(duì)于一個(gè)列表最簡單的去重方法就是直接調(diào)用set函數(shù),利用集合元素的唯一性,就可以做到去重。但是,這個(gè)底層原理究竟是什么樣的卻一直半解。
且看下面剖析
二、重新set實(shí)現(xiàn)機(jī)制
class Foo:
def __init__(self,name,count):
self.name = name
self.count = count
def __hash__(self):
print("%s調(diào)用了哈希方法"%self.name)
return hash(id(self))
def __eq__(self, other):
print("%s調(diào)用了eq方法")
if self.__dict__ == other.__dict__:
return True
else:return False
f1 = Foo('f1',1)
f2 = Foo('f2',2)
f3 = Foo('f3',3)
ls = [f1,f2,f3]
print(set(ls))
從上面可以看出,set方法就是去調(diào)用hash方法,然后根據(jù)哈希值一不一樣就行去重判斷,但是事實(shí)就是樣嗎?且看下面程序。
class Foo:
def __init__(self,name,count):
self.name = name
self.count = count
def __hash__(self):
print("%s調(diào)用了哈希方法"%self.name)
return hash(self.count)
def __eq__(self, other):
print("%s調(diào)用了eq方法"%self.name)
return self.__dict__ == other.__dict__
f1 = Foo('f1',1)
f2 = Foo('f2',1)
f3 = Foo('f3',3)
ls = [f1,f2,f3]
print(set(ls))
我看可以看出,實(shí)際上f1,f3的哈希值是相等的,但是set并沒有這么簡單就判斷f1,f3是重復(fù)的,而是進(jìn)一步通過eq方法判斷這兩個(gè)值是否相等,只有相等時(shí)才會(huì)認(rèn)為這兩個(gè)之間實(shí)際上是同一個(gè)。為了驗(yàn)證上面的說法,我們來看看下面的代碼。
f1 = Foo('f1',1)
f2 = Foo('f1',1)
f3 = Foo('f3',3)
ls = [f1,f2,f3]
print(set(ls))
可以看出去重后,只有兩個(gè)元素,所以上面說法得證。
三、結(jié)論
set的去重是通過兩個(gè)函數(shù)__hash__和__eq__結(jié)合實(shí)現(xiàn)的。
1、當(dāng)兩個(gè)變量的哈希值不相同時(shí),就認(rèn)為這兩個(gè)變量是不同的
2、當(dāng)兩個(gè)變量哈希值一樣時(shí),調(diào)用__eq__方法,當(dāng)返回值為True時(shí)認(rèn)為這兩個(gè)變量是同一個(gè),應(yīng)該去除一個(gè)。返回FALSE時(shí),不去重
四、應(yīng)用場(chǎng)景需求
有一個(gè)公司,現(xiàn)有100個(gè)員工,由于數(shù)據(jù)庫不完善,使用時(shí)間比較長,里面有很多重復(fù)數(shù)據(jù)需要清除。具體需求如下:
每個(gè)員工的屬性有:姓名,性別,年齡,部門。 由于年齡和部門都會(huì)發(fā)生變化,所以現(xiàn)在認(rèn)為只要兩個(gè)員工之間姓名和性別一樣,就認(rèn)為是同一個(gè)人。
請(qǐng)實(shí)現(xiàn)員工去重:
class Staff:
def __init__(self,name,gender,age,department):
self.name = name
self.gender = gender
self.age = age
self.department = department
def __hash__(self):
return hash(self.name+self.gender)
def __eq__(self, other):
return True
ls = ['zs','ls','ww','zq']
gender_list = ['man','femal']
staff_list = []
for i in range(100):
staff_list.append(Staff(ls[i%4],gender_list[i%2],i,'class'))
print(set(staff_list))
print([(i.name,i.gender) for i in set(staff_list)])到此這篇關(guān)于python set()去重的底層原理的文章就介紹到這了,更多相關(guān)python set()去重內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Pandas數(shù)據(jù)清洗的實(shí)現(xiàn)
在處理數(shù)據(jù)的時(shí)候,需要對(duì)數(shù)據(jù)進(jìn)行一個(gè)清洗過程,本文就來介紹一下Pandas數(shù)據(jù)清洗的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-11-11
Python實(shí)現(xiàn)屏幕代碼雨效果的示例代碼
這篇文章主要介紹了如何利用Python中的Pygame模塊實(shí)現(xiàn)代碼雨效果,文中通過示例代碼介紹的非常詳細(xì),感興趣的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-03-03
python實(shí)現(xiàn)本地批量ping多個(gè)IP的方法示例
這篇文章主要介紹了python實(shí)現(xiàn)本地批量ping多個(gè)IP的方法示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
Pandas+openpyxl進(jìn)行Excel處理詳解
這篇文章主要為大家詳細(xì)介紹了如何使用pandas和openpyxl庫對(duì)多個(gè)Excel文件進(jìn)行多種處理的方法,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2025-02-02
Django中對(duì)通過測(cè)試的用戶進(jìn)行限制訪問的方法
這篇文章主要介紹了Django中對(duì)通過測(cè)試的用戶進(jìn)行限制訪問的方法,Django是眾多Python高人氣web框架中最為著名的一個(gè),需要的朋友可以參考下2015-07-07
Python+random模塊實(shí)現(xiàn)隨機(jī)抽樣
python的random庫,提供了很多隨機(jī)抽樣方法。本文將通過幾個(gè)示例為大家詳細(xì)講講random模塊實(shí)現(xiàn)隨機(jī)抽樣的方法,需要的可以參考一下2022-09-09
Python 中的Schema數(shù)據(jù)結(jié)構(gòu)及類型校驗(yàn)詳解
schema?是一個(gè)簡單而強(qiáng)大的庫,用于定義和驗(yàn)證 Python 數(shù)據(jù)結(jié)構(gòu)的約束,使用?schema?庫來執(zhí)行數(shù)據(jù)結(jié)構(gòu)的校驗(yàn),本文給大家介紹Python 中的Schema數(shù)據(jù)結(jié)構(gòu)及類型校驗(yàn),感興趣的朋友一起看看吧2023-11-11
利用 Python 實(shí)現(xiàn)隨機(jī)相對(duì)強(qiáng)弱指數(shù) StochRSI
隨機(jī)相對(duì)強(qiáng)弱指數(shù)簡稱為StochRSI,是一種技術(shù)分析指標(biāo),用于確定資產(chǎn)是否處于超買或超賣狀態(tài),也用于確定當(dāng)前市場(chǎng)的態(tài)勢(shì)。本篇文章小編九來為大家介紹隨機(jī)相對(duì)強(qiáng)弱指數(shù)簡稱為StochRSI,需要的朋友可以參考下面文章的具體內(nèi)容2021-09-09

