python set()去重的底层原理及实例

目录
  • set是什么?
  • set特点
  • 一、set去重简单实例
  • 二、重新set实现机制
  • 三、结论
  • 四、应用场景需求

set是什么?

数学上,把set称做由不同的元素组成的集合,集合(set)的成员通常被称做集合元素(set elements)。Python把这个概念引入到它的集合类型对象里。集合对象是一组无序排列的可哈希的值。集合关系测试和union、intersection等操作符在Python里也同样如我们所预想地那样工作。

set特点

集合的元素有三个特征:

1.确定性:集合中的元素必须是确定的;

2.互异性:集合中的元素互不相同,如:集合A={1,a},则a不能等于1);

3.无序性:集合中的元素没有先后之分,如:{3,4,5}和{3,5,4}算作同一个集合。

python中集合(set)是一个无序不重复元素的集,基本功能包括关系测试和消除重复元素,还可以计算交集、差集、并集等,它与列表(list)的行为类似,区别在于set不同包括重复的值,而且set元素是无序的。

在python中可以用大括号 {} 创建集合。注意:如果要创建或初始化一个空集合,你必须用 set() 而不是 {} 。因为后者{} 作为创建一个空的字典,以后我们会介绍字典这种数据结构。

一、set去重简单实例

ls = [1,2,3,1,2]
print(set(ls))

我们知道对于一个列表最简单的去重方法就是直接调用set函数,利用集合元素的唯一性,就可以做到去重。但是,这个底层原理究竟是什么样的却一直半解。

且看下面剖析

二、重新set实现机制

class Foo:
    def __init__(self,name,count):
        self.name = name
        self.count = count
    def __hash__(self):
        print("%s调用了哈希方法"%self.name)
        return hash(id(self))
    def __eq__(self, other):
        print("%s调用了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方法就是去调用hash方法,然后根据哈希值一不一样就行去重判断,但是事实就是样吗?且看下面程序。

class Foo:
    def __init__(self,name,count):
        self.name = name
        self.count = count
    def __hash__(self):
        print("%s调用了哈希方法"%self.name)
        return hash(self.count)
    def __eq__(self, other):
        print("%s调用了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))

我看可以看出,实际上f1,f3的哈希值是相等的,但是set并没有这么简单就判断f1,f3是重复的,而是进一步通过eq方法判断这两个值是否相等,只有相等时才会认为这两个之间实际上是同一个。为了验证上面的说法,我们来看看下面的代码。

f1 = Foo('f1',1)
f2 = Foo('f1',1)
f3 = Foo('f3',3)
ls = [f1,f2,f3]
print(set(ls))

可以看出去重后,只有两个元素,所以上面说法得证。

三、结论

set的去重是通过两个函数__hash__和__eq__结合实现的。
1、当两个变量的哈希值不相同时,就认为这两个变量是不同的
2、当两个变量哈希值一样时,调用__eq__方法,当返回值为True时认为这两个变量是同一个,应该去除一个。返回FALSE时,不去重

四、应用场景需求

有一个公司,现有100个员工,由于数据库不完善,使用时间比较长,里面有很多重复数据需要清除。具体需求如下:

每个员工的属性有:姓名,性别,年龄,部门。 由于年龄和部门都会发生变化,所以现在认为只要两个员工之间姓名和性别一样,就认为是同一个人。

请实现员工去重:

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)])

到此这篇关于python set()去重的底层原理的文章就介绍到这了,更多相关python set()去重内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python 利用内置set函数对字符串和列表进行去重的方法

    如下所示: # coding:utf8 __author__ = 'libingxian' __date = "20170415" # 由于数据类型set本身具有无序,唯一值的特性,可以用内置函数set对字符串和列表进行去重,挺方便的 str = "asdfasdlklfgklgjsdfjkjl" se = set(str) print se li = [1,"2",1,"2","abc","12

  • 对python读写文件去重、RE、set的使用详解

    如下所示: # -*- coding:utf-8 -*- from datetime import datetime import re def Main(): sourcr_dir = '/data/u_lx_data/fudan/muying/muying_11yue_all.txt' target_dir = '/data/u_lx_data/fudan/muying/python/uid_regular_get.txt' uset = set() #去重 print("开始.....&q

  • python set()去重的底层原理及实例

    目录 set是什么? set特点 一.set去重简单实例 二.重新set实现机制 三.结论 四.应用场景需求 set是什么? 数学上,把set称做由不同的元素组成的集合,集合(set)的成员通常被称做集合元素(set elements).Python把这个概念引入到它的集合类型对象里.集合对象是一组无序排列的可哈希的值.集合关系测试和union.intersection等操作符在Python里也同样如我们所预想地那样工作. set特点 集合的元素有三个特征: 1.确定性:集合中的元素必须是确定的

  • Python 异步协程函数原理及实例详解

    这篇文章主要介绍了Python 异步协程函数原理及实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 一. asyncio 1.python3.4开始引入标准库之中,内置对异步io的支持 2.asyncio本身是一个消息循环 3.步骤: (1)创建消息循环 (2)把协程导入 (3)关闭 4.举例: import threading # 引入异步io包 import asyncio # 使用协程 @ asyncio.coroutine def

  • python神经网络Batch Normalization底层原理详解

    目录 什么是Batch Normalization Batch Normalization的计算公式 Bn层的好处 为什么要引入γ和β变量 Bn层的代码实现 什么是Batch Normalization Batch Normalization是神经网络中常用的层,解决了很多深度学习中遇到的问题,我们一起来学习一哈. Batch Normalization是由google提出的一种训练优化方法.参考论文:Batch Normalization Accelerating Deep Network T

  • Python字典的核心底层原理讲解

    字典对象的核心是散列表.散列表是一个稀疏数组(总是有空白元素的数组),数组的每个单元叫做 bucket.每个 bucket 有两部分:一个是键对象的引用,一个是值对象的引用.所有 bucket 结构和大小一致,我们可以通过偏移量来读取指定 bucket.下面通过存储与获取数据的过程介绍字典的底层原理. 存储数据的过程 例如,我们将'name' = '张三' 这个键值对存储到字典map中,假设数组长度为8,可以用3位二进制表示. >>> map = {} >>> map

  • Python函数用法和底层原理分析

    目录 Python函数用法和底层分析 函数的基本概念 Python 函数的分类 核心要点 形参和实参 文档字符串(函数的注释) 返回值 函数也是对象,内存底层分析 变量的作用域(全局变量和局部变量) 部变量和全局变量效率测试 参数的传递 传递不可变对象的引用 浅拷贝和深拷贝 传递不可变对象包含的子对象是可变的情况 参数的几种类型 位置参数 默认值参数 命名参数 可变参数 强制命名参数 lambda 表达式和匿名函数 eval()函数 递归函数 Python函数用法和底层分析 函数是可重用的程序代

  • Python闭包与装饰器原理及实例解析

    一.闭包 闭包相当于函数中,嵌套另一个函数,并返回.代码如下: def func(name): # 定义外层函数 def inner_func(age): # 内层函数 print('name: ', name, ', age: ', age) return inner_func # 注意此处要返回,才能体现闭包 bb = func('jayson') # 将字符串传给func函数,返回inner_func并赋值给变量 bb(28) # 通过变量调用func函数,传入参数,从而完成闭包 >>

  • Python多进程与服务器并发原理及用法实例分析

    本文实例分析了Python多进程与服务器并发原理及用法.分享给大家供大家参考,具体如下: 进程 什么是进程 进程:正在进行的一个过程或者说一个任务.而负责执行任务则是cpu. 进程与程序的区别 程序仅仅只是一堆代码而已,而进程指的是程序的运行过程. 并发与并行 无论是并行还是并发,在用户看来都是'同时'运行的,不管是进程还是线程,都只是一个任务而已,真是干活的是cpu,cpu来做这些任务,而一个cpu同一时刻只能执行一个任务 一 并发:是伪并行,即看起来是同时运行.单个cpu+多道技术就可以实现

  • Python matplotlib底层原理解析

    目录 1. matplotlib 框架组成 2. 脚本层(scripting) 3. 美工层(artist) 4. 后端层(backend) 复习回顾: 前期,我们已经学习了matplotlib模块相关的基础知识,对 matplotlib 模块折线图.饼图.柱状图进行操作. 我们都知道matplotlib 是偏向底层用于可视化数据处理的库,我们在绘制图表的时候主要步骤主要有四大步骤: 导入 matplotlib.pplot库 使用pandas/numpy模块对数据进行整分析理 调用pyplot中

  • Python实现的插入排序算法原理与用法实例分析

    本文实例讲述了Python实现的插入排序算法原理与用法.分享给大家供大家参考,具体如下: 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2).是稳定的排序方法 插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素).在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中. 插

  • Python设计模式之解释器模式原理与用法实例分析

    本文实例讲述了Python设计模式之解释器模式原理与用法.分享给大家供大家参考,具体如下: 解释器模式(Interpreter Pattern):给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 下面是一个解释器模式的demo: #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'Andy' """ 大话设计模式 设计模式--解释器模式 解释器模式(Interpr

随机推荐