Python--几种set集合去重的方法

本文详细解析了Python中set集合的去重机制,并通过具体示例代码展示了如何利用hash和eq方法实现对象去重。此外,还介绍了几种常见的列表去重方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.set集合的去重机制

ps: set集合在内部执行时,首先会先对对象执行hash算法,存储到内存空间,

(但在同一次运行过程中两个值相等的对象hash值一样)所以如果两个对象值相等,这时会做出第二步操作,

判断这两个对象的值是否相等,若相等覆盖,若不等则进行二次寻址,存储到空间;

*****那么问题来了!!!*****

看下面这道题:

1)创建一个员工管理系统      2)对象的属性为:姓名,年龄,性别,部门  

3)在公司的日志中可能有的员工会出现内部转岗的情况,所以会有重复的信息

4)现有200个员工,如果几个员工对象的姓名和性别相同,那么这是同一个人,进行去重操作

class Person:
	def __init__(self,name,sex,age,partment):
		self.name = name
		self.sex = sex
		self.age = age
		self.partment = partment
	def __hash__(self):
		return hash((self.name,self.sex))
	def __eq__(self, other):
		if self.name == other.name and self.age == other.age:
			return True
employeeList = []
for i in range(3):
	employeeList.append(Person('li','男',15,'Python'))
for i in range(3):
	employeeList.append(Person('wu', '男', 15, '运维'))
for i in range(3):
	employeeList.append(Person('alex', '男', 15, 'linux'))

obj = set(employeeList)
for i in obj:
	print(i.__dict__)
#set集合会先触发对象的__hash__方法,如果hash值相等,再触发__eq__方法进行去重操作

输出结果:

{'name': 'li', 'sex': '男', 'age': 15, 'partment': 'Python'}
{'name': 'wu', 'sex': '男', 'age': 15, 'partment': '运维'}
{'name': 'alex', 'sex': '男', 'age': 15, 'partment': 'linux'}

总结:set集合去重机制是先对对象进行hash,如若hash值相等,再比较两个值是否相等,如若不等,则进行二次寻址;

这个算法设计具有一定的可靠性;

2.几种set集合去重的办法

1)直接使用

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


#结果:[1, 2, 3, 4, 5]
#为什么结果是排序之后的结果呢,因为数字的hash值是它本身

2)列表推导式

ls = [1,2,2,3,5,5,4,4]
new_ls = []
[new_ls.append(i) for i in ls if i not in new_ls]
print(new_ls)


#结果:[1, 2, 3, 5, 4]

3)keys()方法:

ls = [1,2,2,3,5,5,4,4]
print(list(dict.fromkeys(ls).keys()))


#结果:[1, 2, 3, 5, 4]

4.按照索引再次排序:

ls = [1,2,2,3,5,5,4,4]
obj = list(set(ls))
obj.sort(key=ls.index)
print(obj)
#结果:[1, 2, 3, 5, 4]

装饰器

# ----展开版(装饰器携带参数----
def test2():
    print('test2')


def fn(f):
    # 嵌套多层,接收参数
    def outter(fun):
        def inner():
            print(f)
            fun()
            print('hou')

        return inner
    return outter


outter = fn('qq')
inner = outter(test2)
inner()
# ---正规版---
def fun(f):
    def outter(fun):
        def inner():
            print(f)
            fun()
            print('后')
        return inner
    return outter


@fun('qq')
def test1():
    print('test1')


test1()

关于装饰器的题目:

  • 实现一个装饰器,限制该函数调用频率,如10秒一次
  • import time
    
    
    def fun(fn):
        dic = {}
    
        def inner(*args, **kwargs):
    
            if not dic.get(fn):
                print('执行函数')
                dic.setdefault(fn, time.time())
                return fn(*args, **kwargs)
            else:
                print(time.time())
                if time.time() - dic.get(fn) > 0.01:
                    return '不执行函数'
                else:
                    print('时间通过,执行函数')
                    return fn(*args, **kwargs)
    
        return inner
    
    
    @fun
    def test(f):
        return 111
    
    
    # for i in range(0, 800):
    #     print(test(i))
    
    @fun
    def test2():
        return 222
    
    
    print(test2())

     

<think>我们之前讨论了数据库存储结构(表空间、段、区、数据块等),现在用户转向数据技术。用户引用了四篇文献,但请注意这些引用是站内引用,可能来自之前的对话或知识库。根据用户当前问题,他想了解数据几种方法,特别是在数据处理和数据库操作中常见的技术。用户问题:"我想了解几种方法,可能用于数据处理或数据库操作请问数据方法数据库算法常见技术"根据引用内容:引用[1]:数据库中的数据,删除复数据的过程,提高数据库性能和质量。引用[2]:数据的核心概念:相似性度量(欧氏距离、余弦相似度等)、算法(基于哈希表、基于聚类等)、优化(数据预处理、索引等)。引用[3]:利用Redis进行数据,使用Redis和hash算法(如用Redis的集合存储已处理的URL)。引用[4]:数据仓库,提到排序算法和外排序(当数据大于内存时)。因此,我们需要围绕这些点展开,点介绍数据库和数据处理中常用的方法,包括算法和优化技术。我将从以下几个方面组织回答:1.精确(适用于完全相同的复数据)2.相似(适用于相似但不完全相同的数据,如文本相似、图像相似)3.分布式环境下(如使用Redis)4.大数据场景下的优化(如外排序)同时,注意用户可能的应用场景:数据库操作(SQL)和数据处理(编程实现)。结构:一、精确a.数据库SQL(DISTINCT,GROUPBY)b.哈希表法(编程实现)c.排序法(先排序后)二、相似(模糊)a.基于相似性度量的方法(如余弦相似度、Jaccard相似度)b.基于局部敏感哈希(LSH)c.基于聚类的(如K-means)三、分布式a.使用Redis集合(存储已出现的数据标识)b.布隆过滤器(BloomFilter)四、大数据优化a.外排序(处理超出内存的数据)b.索引优化(加速查询)c.并行处理(分片)最后,给出相关问题。注意:在介绍方法时,尽量结合实例(如SQL语句、Python代码片段)和适用场景。</think>### 数据方法详解 数据是数据处理的核心技术,根据应用场景可分为**精确**和**相似**两类。以下是主流方法的技术实现与优化策略: --- #### 一、精确(完全匹配) 1. **数据库原生方法** ```sql -- DISTINCT关键字 SELECT DISTINCT name FROM users; -- GROUP BY聚合 SELECT name, COUNT(*) FROM sales GROUP BY product_id HAVING COUNT(*) > 1; ``` **适用场景**:结构化数据快速[^1] 2. **哈希表法** ```python def exact_dedupe(data_list): seen = set() unique_data = [] for item in data_list: item_hash = hash(item) # 或使用MD5/SHA1 if item_hash not in seen: seen.add(item_hash) unique_data.append(item) return unique_data ``` **时间复杂度**:$O(n)$ **内存优化**:布隆过滤器(Bloom Filter)降低内存占用[^3] --- #### 二、相似(模糊匹配) 1. **局部敏感哈希(LSH)** - 将相似数据映射到相同桶中 - **实现流程**: ```mermaid graph LR 原始数据-->特征向量 特征向量-->LSH投影 投影值-->哈希桶 哈希桶-->桶内 ``` 2. **文本相似度算法** | 算法 | 原理 | 适用场景 | |------|------|----------| | Jaccard相似度 | $J(A,B) = \frac{|A \cap B|}{|A \cup B|}$ | 短文本/集合数据 | | 余弦相似度 | $\cos \theta = \frac{\vec{a} \cdot \vec{b}}{\|\vec{a}\| \|\vec{b}\|}$ | 文档/向量化数据 | | MinHash | 近似计算Jaccard相似度 | 海量数据[^2] | 3. **聚类** ```python from sklearn.cluster import DBSCAN from sklearn.feature_extraction.text import TfidfVectorizer def cluster_dedupe(texts): vectorizer = TfidfVectorizer() X = vectorizer.fit_transform(texts) clusters = DBSCAN(eps=0.5).fit(X) return {cluster_id: texts[indices] for cluster_id, indices in clusters.items()} ``` --- #### 三、大数据优化技术 1. **分治策略** - 使用MapReduce实现分布式: ```java // Mapper输出<Key, Value> map(key, value) { emit(value, null); // Value作为Key } // Reducer自动 reduce(key, values) { emit(key); } ``` 2. **外排序** **步骤**: 1. 数据分块载入内存 2. 每块内部排序 3. 归并排序合并块 4. 合并时跳过复值[^4] **适用场景**:数据量 > 内存容量 3. **增量** - 使用Redis存储已处理数据标识: ```python import redis r = redis.Redis() def is_duplicate(item): item_hash = hashlib.sha256(item.encode()).hexdigest() if r.sismember("processed_items", item_hash): return True r.sadd("processed_items", item_hash) return False ``` --- #### 四、方法对比与选型 | 方法 | 精度 | 速度 | 内存消耗 | 适用场景 | |------|------|------|----------|----------| | 哈希表 | 100% | 快 | 高 | 小数据集 | | 布隆过滤器 | 99.9% | 极快 | 极低 | URL[^3] | | LSH | 近似 | 中 | 中 | 相似图片/文档 | | 外排序 | 100% | 慢 | 低 | 超大数据集 | --- #### 五、最佳实践建议 1. **结构化数据**:优先使用数据库`DISTINCT`/`GROUP BY` 2. **流式数据**:Redis布隆过滤器 + 定时持久化 3. **非结构化数据**: - 文本:MinHash + LSH - 图像:感知哈希(pHash) 4. **海量数据**:分治策略 + 分布式计算框架(Spark/Flink) > 注:实际应用中常组合多种方法,如先用哈希快速过滤完全复项,再用相似算法处理模糊复[^2]。 --- ### 相关问题 1. 布隆过滤器的误判率如何计算?如何降低误判? 2. MinHash和SimHash在文本中的性能差异是什么? 3. 如何处理高维向量数据的问题? 4. 在分布式环境下如何保证操作的幂等性? 5. 数据与数据压缩技术如何结合使用?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值