当前位置: 首页
业界动态
还在乱用列表?集合 set 才是去重和效率神器

还在乱用列表?集合 set 才是去重和效率神器

热心网友 时间:2026-04-15
转载

不是会不会写代码,而是会不会选结构

你有没有遇到过这种情况:为了给列表去重,吭哧吭哧写了好几行循环判断,结果数据量一大,程序就慢得让人心焦。或者,想判断一个元素在不在列表里,程序直接“卡成狗”。

这其实不是代码逻辑的问题,而是数据结构没选对。很多Python初学者都有一个共同的习惯:遇到问题,下意识就用列表(list)来解决一切。但你可能不知道,在某些特定场景下,集合(set)才是真正的“降维打击”神器。

回想一下,你是不是写过这样的代码?

users = [1001, 1002, 1002, 1003, 1003, 1003]
result = []
for u in users:
    if u not in result:
        result.append(u)

写完可能觉得:“逻辑清晰,能跑就行”。但现实往往很骨感:一旦数据量上来,性能就会暴跌;代码越堆越长,逻辑也越来越绕。

问题的根源在于,你用错了工具。在真实的开发世界里,选对数据结构,性能提升十倍起步是常有的事。

为什么list会越来越慢?

来看一个最常见的操作:在一个列表中查找某个元素是否存在。

nums = list(range(1000000))
999999 in nums

这行代码在底层做了什么?它需要从列表的第一个元素开始,一个一个地问:“是你吗?”,直到找到目标或者问完所有人。这种查找方式,在算法复杂度里被称为 O(n)。简单说,就是数据量(n)越大,查找所花的时间就越长,呈线性增长。

你可以把它想象成在一条长长的队伍里“排队找人”,必须从头到尾一个个看过去。

set 为什么是效率神器?

同样的任务,换成集合(set)试试:

nums = set(range(1000000))
999999 in nums

几乎是瞬间完成。为什么差距这么大?因为集合的底层实现是哈希表(Hash Table)。

这好比什么呢?列表是“排队找人”,而集合是“直接查身份证号”。每个元素进入集合时,都会根据其值计算出一个唯一的“地址”(哈希值)。查找时,直接去这个地址看一眼就知道有没有,根本不需要遍历。

它的时间复杂度是 O(1),意味着查找时间基本不受数据总量影响,这才是真正的“数据结构碾压”。

去重的3种写法(90%的人只会第一种)

明白了原理,再来看去重这个经典问题。其实写法不止一种,但效率天差地别。

❌ 写法1:低效循环版

result = []
for n in nums:
    if n not in result:
        result.append(n)

这是最直观的写法,但效率最低。因为每次`n not in result`都要遍历一次结果列表,整体时间复杂度达到了 O(n²)。数据量稍大,就能明显感觉到卡顿。

✅ 写法2:set去重(最常用)

result = list(set(nums))

这是最经典的用法,利用集合自动去重的特性,一行代码搞定,速度极快。但有一个需要注意的问题:原始顺序会丢失。因为集合本身是无序的。

? 写法3:保序去重(推荐)

result = list(dict.fromkeys(nums))

如果你需要保留元素第一次出现的顺序,推荐这个方法。它的原理很巧妙:从Python 3.7开始,字典(dict)会保持键(key)的插入顺序。同时,字典的键本身就是不重复的。`dict.fromkeys(nums)`会以nums的元素为键创建一个新字典,自动去重并保序,最后再转回列表即可。

真实项目场景

理论说再多,不如看几个实战场景。

场景1:百万级用户ID去重

user_ids = load_data() # 假设这里加载了百万条数据
unique_users = set(user_ids)

用列表循环可能需要几秒甚至更久,而用集合,往往是几毫秒的事。这在处理日志、用户行为数据时非常实用。

场景2:黑名单快速过滤

blacklist = {1002, 1005, 1010}
users = [1001, 1002, 1003]
safe_users = [u for u in users if u not in blacklist]

将黑名单定义为集合,使得`u not in blacklist`这个判断变成了O(1)的瞬时操作,即使黑名单很大,过滤速度也极快。

场景3:寻找共同好友(集合运算)

a = {1, 2, 3} # 用户A的好友集合
b = {2, 3, 4} # 用户B的好友集合
print(a & b) # 输出: {2, 3},即共同好友

集合支持交集(&)、并集(|)、差集(-)等数学运算,在社交、推荐系统等需要比较群体关系的场景下非常方便。

set 的隐藏技巧

除了去重和查找,集合还有一些巧妙的用法:

自动去重并清理空值:

data = [1, 2, None, 2, None]
clean = {x for x in data if x is not None}
# 结果: {1, 2}

结合集合推导式,可以一步完成过滤和去重。

快速提取字符串中的唯一字符:

text = "aaabbbccc"
print(set(text)) # 输出: {'a', 'b', 'c'}

一行代码判断列表是否有重复元素:

def has_duplicate(nums):
    return len(nums) != len(set(nums))
# 如果列表长度和去重后的集合长度不等,说明一定有重复。

set 的三个大坑

当然,集合并非万能,使用时也要避开几个常见的“坑”:

❌ 无序性:集合中的元素没有固定的顺序。

print(set([3, 1, 2])) # 输出可能是 {1, 2, 3},也可能是其他顺序。

❌ 不能存放可变对象:集合的元素必须是“可哈希的”(hashable)。像列表、字典这类可变对象是不可哈希的,不能作为集合元素。

s = {[1, 2]} # 报错!TypeError: unhashable type: 'list'

❌ 非线程安全(进阶注意):在多个线程同时修改同一个集合时,可能会遇到问题。这在高级并发编程中需要留意。

list vs set 认知升级

很多人在学习Python时感到进步缓慢,问题往往不在于不会写`for`循环或`if`判断,而是一直在用“错误的工具”解决问题。

真正的编程高手思维包含两个层面:一是“我该怎么写这段代码”,二是“我应该用什么数据结构来组织我的数据”。后者往往更能决定程序的效率和优雅程度。

记住一个核心原则:凡是涉及成员查找(`in`操作)或去重的场景,优先考虑使用集合(set),而不是列表(list)。

最后给你一个练习

为了巩固理解,可以尝试实现一个函数,输入一个列表,要求返回:

  1. 去重后的结果(保留原始顺序)。
  2. 一个布尔值,指示原列表是否存在重复元素。
  3. 一个列表,包含所有重复出现的元素(每个重复元素只列一次)。

试试看,你会如何设计?

来源:https://www.51cto.com/article/840181.html

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
苹果人工智能服务器芯片Baltra或将用于执行推理任务

苹果人工智能服务器芯片Baltra或将用于执行推理任务

苹果一贯的策略是:只要技术条件允许,就会将关键环节牢牢掌握在自己手中。早在2024年,业内就多次传出消息称,苹果正与博通合作开发一款AI服务器芯片,内部代号为Baltra。根据当时的报道,这款芯片将采用台积电的3纳米N3E工艺,整个设计周期预计在12个月内完成。如今,Baltra已不再是传闻中的概念

时间:2026-07-03 14:00
蝉联全球AR智能眼镜第一 雷鸟创新Q3海外增长近四倍

蝉联全球AR智能眼镜第一 雷鸟创新Q3海外增长近四倍

2025年12月15日,Counterpoint Research发布的季度报告为全球AR眼镜市场竞争格局增添了全新注脚。数据显示,中国品牌雷鸟创新(RayNeo)以24%的市场份额,连续两个季度稳居全球AR智能眼镜榜首。与此同时,IDC、CINNO Research等多家权威机构的报告均指向同一结

时间:2026-07-03 13:59
当虹科技打造可落地机器人学长逛校园教育场景

当虹科技打造可落地机器人学长逛校园教育场景

12月10日至11日,杭州第二中学2025学术节上,一位特殊的“学长”成为全校师生争相围观的焦点。这台搭载当虹科技“机器人+教育”场景解决方案的人形机器人,不仅能在校园内自主行走、与人流畅对话,更自带一股亲切的“学霸”气质——师生们热情地称它为“二中智兔”。说实话,当一台机器人站在校门口主动向你问好

时间:2026-07-03 13:59
晶科电子荣获多项权威奖项技术引领全球加速彰显LED+智能视觉成长价值

晶科电子荣获多项权威奖项技术引领全球加速彰显LED+智能视觉成长价值

先说说核心判断:晶科电子这一轮接连荣获四项重磅奖项,覆盖权威媒体、产业机构与资本市场,这背后不仅仅体现了公司在技术与布局上的深厚积累,更反映出港股市场对硬科技制造赛道价值认知的一次系统性修复。 近一个月内,广东晶科电子股份有限公司(简称:晶科电子,股票代码:2551 HK)连续斩获四个具有分量的荣誉

时间:2026-07-03 13:59
上海海思谛听筑芯 智能穿戴腕上革命新标杆

上海海思谛听筑芯 智能穿戴腕上革命新标杆

智能穿戴领域的竞争发展到今天,早已不再单纯比拼硬件参数。真正的较量,在于生态融合的能力和系统整体的体验。 不妨听听当下消费者在追问什么——我的手表能不能更懂我?它的健康监测是否真正可靠?脱离手机后,它还能独立、智能地替我处理事务吗?这些问题的答案,其实并不取决于某一颗传感器有多强,或者某一块屏幕有多

时间:2026-07-03 13:59
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜