惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Heimdal Security Blog
P
Privacy International News Feed
S
Schneier on Security
P
Proofpoint News Feed
L
Lohrmann on Cybersecurity
Spread Privacy
Spread Privacy
P
Privacy & Cybersecurity Law Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Scott Helme
Scott Helme
K
Kaspersky official blog
大猫的无限游戏
大猫的无限游戏
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
aimingoo的专栏
aimingoo的专栏
Simon Willison's Weblog
Simon Willison's Weblog
S
Securelist
Help Net Security
Help Net Security
B
Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Security Archives - TechRepublic
Security Archives - TechRepublic
云风的 BLOG
云风的 BLOG
The GitHub Blog
The GitHub Blog
N
News and Events Feed by Topic
Hacker News: Ask HN
Hacker News: Ask HN
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
M
MIT News - Artificial intelligence
雷峰网
雷峰网
博客园 - 司徒正美
V
V2EX
AWS News Blog
AWS News Blog
Know Your Adversary
Know Your Adversary
N
News | PayPal Newsroom
T
Tor Project blog
Cisco Talos Blog
Cisco Talos Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
PCI Perspectives
PCI Perspectives
Google DeepMind News
Google DeepMind News
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
U
Unit 42
C
Cybersecurity and Infrastructure Security Agency CISA
P
Palo Alto Networks Blog
G
Google Developers Blog
T
Threat Research - Cisco Blogs
博客园 - Franky
I
InfoQ
D
DataBreaches.Net
爱范儿
爱范儿
Y
Y Combinator Blog
博客园 - 叶小钗
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报

推广

Codex 助力小项目,全部重写了一遍,有点意思! 管转满血模型 GPT-5.5 / gpt-image-2 API 已上线,倍率调低 0.3,注册留 ID 送 5 美金额度 GPT-5.5 / gpt-image-2 API 已上线, 0.06$/张,注册留 ID 送 5 美金额度 不知道为什么, V2EX 的铜币实在是用不完。今天也没什么特别要宣传的,就随便来发发牢骚,消费一下铜币吧。 腾讯云国际站代充值渠道-支持 USDT 支付-免绑卡注册——LingduCloud 零度云! [发 15 个码] 开发的 Mac 应用 Deepseek coding plan 限量供应 腾讯云国际企业认证账号出售:阿里云/华为云国际可开国内节点 codex 中转,留邮箱就送。 5.1 香港旅游, Za bank 众安银行开户额外返现 300HKD 目前 GPT Plus 价格已经顶上天了,我们开发了 Pro 200 刀 拼车功能.... 3.3 元 即可上车 GPT5.5 出了? 限时 0.1x 倍率 送刀了 评论区抽 10 刀共*10 阿里云国际站充值代充-官方授权分销商开户——LingduCloud 零度云 [福利] 分享一个完美解锁 GPT-5.4 限制的住宅代理: Novproxy(内附 500M 免费试用) GPT 5.5 上了 0.1x 还不来? SentiCat 开启公测:一款自研架构的桌面 Agent,主打“任务执行+情感陪伴” 自用 OpenAI API 中转 🤡 自己搞了个 AI token 中转,能用 Codex / Claude Code,随便测下 Ai2You 智友社-让更多的人用上更好的 Ai,解决您的 AI 焦虑! 一个英语学习 APP [iOS] ,送 50 个终身会员 [中转] A 社官方满血 Opus-4-7 上线,限时免费开蹬!支持对接 & 开票! aicoding.sh: Claude API 企业级中转服务,数万用户稳定运行 GPT-5.5 上线 0.2x 倍率 Codex Plus/Pro 高缓存号池 持续稳定一个月 5.4 典型用量 8 元一亿 Token 新开业中转站 kir 0.2x GTP 0.1x gpt-image-2 0.08 华为云实名号购买:阿里云|腾讯云实名号免费开 感谢 V2EX 上各位 NAS🍆 和 Datahoarder 玩家的关注和真实反馈!作为个人开发者,能得到这么多硬核玩家们的讨论,我非常荣幸。 今天摸鱼给 NanaAI 也接入了 GPT-Image-2 腾讯云国际站实名账号 LingduCloud 零度云:腾讯云国际站实名账号认证教程! 价格差不多是官方 8 分之一的 codex 渠道,分享给大家 [星问] 紫微斗数 AI 智能解盘送福利了 期权经验分享&晒单 🌍 找稳定代理看这里! Novproxy 动态住宅 IP:注册免费领 500M,全球 200+ 国家覆盖 🛰️ [www.DDShub.cc] 呆呆兽中转站,满血 Claude/CodeX [AI 中转站] 球球 Token - AI 聚合中转服务站 拉新活动 已支持 CodeX、Claude Code 华为云国际站实名账号代充值 LingduCloud 零度云:华为云国际站 ECS 服务器使用教程! 中转站正式试营 欢迎试用 不掺不假 老牌号商不跑路 再来安利一个中年男人的兴趣论坛 M 站, 风格有点像大疆/理想? 功能也很有趣, 总归是能多一个 ~~摸鱼~~ 交友的地方 [岁岁-极简农历日程] 没找到好用的农历日程提醒 App,所以我自己撸了一个:无广告、支持系统日历日程写入 做了一个自己的 AI 中转站,球球 Token,现支持 CodeX 和 Claude Code 麋鹿云送福利啦 [Codex 中转站]不跑路的老王送福利了,新用户即送 10$ 🔥Racknerd 全新套餐上架(涨价了,机房选择也变多了) 做了一个 GPT Image 2 生成器,不得不说 GPT Image 2 生成的美女真漂亮 $10 FREE| 用 Claude Code 写代码,付费只需官方价 1.9 折 这些图是 GPT-Image-2 出的?效果炸裂!可以来我的 gpt-image-2.me 网站体验 中转站正式试营 欢迎试用 不掺不假 claude code / codex 免费 API 来了 [Codex 中转站]HyperAPI 又来送福利了,新用户注册即送 5$, 评论留下邮箱送 5$兑换卷 华为云国际站实名账号代理商 LingduCloud 零度云:华为云国际站实名账号认证教程! 新机器人开 team 这个权威的中转站现在有活动,注册就能领体验金 为什么我选择在这里打破沉默?一个独立开发者的自白:从 NAS 积灰到“零解压秒开”的终极救赎 (附日文原稿) 🚀 招募出海合伙人:我出技术和流量,你来赚差价! 200G 客户测试份额免费领 可以免费白嫖 GPT Image 2 的网站,每天都有刷新额度 V2EX › 登录 从零开始,在国内网络跑通 Claude Code 等一切 Agent 框架 小龙虾和爱马仕已经 out 了 AI 最强 Agent 小龙猫才是 YYDS lingducloud:海外云服务器购买避坑指南 [中转站推广] AIHub2API 中转站送福利,本站新用户送 6 刀,每 10 楼抽 1 张 100 刀日卡 Kookeey 动态住宅 IP:全网底价,支持动态免费测试 国际阿里云实名账号代理商 LingduCloud 零度云: 2026 最新阿里云国际站实名账号注册教程! 平台的特价稳定渠道 GPT Pro 系列马上绝版,需要的 NS 兄弟别错过 [公测] APIBox 中转站推广送福利💥 Claude Code 被封号无数?防封号终极指南,字字千金, 12 条硬核规则助你构建'正常人类行为档案'! - V2EX [薅羊毛] 纯净住宅代理 IP 免费领, Novproxy 新人专属 CDK,手慢无! [福利/AI 中转站]OneXModel 新注册送 10$体验金,官方纯血 claude 最低 2.2 折!极致性价比! $10 FREE | Claude API 官方价一折起,国内直连无需折腾 火山方舟的 coding plan 上线新模型了,支持最新开源的 glm 5.1, kimi 2.6 和 minimax-m2.7 Claude Pro 不能用 Claude Code? 今天把 GPT Image 2 接进来了,做了个小站可以免费体验 2 次 [福利] 给各位 大佬薅个 1G 动态住宅 IP 羊毛,先测再玩! 网易爆米花目前算免费里体验最好的了吧,别和 infuse 比 - V2EX 满血 Claude opus4.7 和 Codex Pro 5.4 美国家宽池,不降智!一个越用越稳的 API 中转站,回帖送美元额度! 不只是 NAS:走出局域网, Nas Player Pro 依然能打 ✨都在说 VMRack 好,我来看看怎么个事 | 测评 L1 L2 L3 三条线路,果然 L3 机器确实很赞,没什么库存,购买靠抢(文末有抢机器的方法) [福利] Mirrorstages 今天免费了! GPT-5.4 随便蹬,顺便聊聊最近 Plus 的漏洞 这种小程序开发报价多少钱合适?给甲方报价 3000 会不会过分 - V2EX Kookeey 动态住宅 IP:全球 180+ 国家,城市定位,支持动态免费测试 🚀 Unity2.Ai 公测招募|直达源头,拒绝降智, aws 企业渠道,新用户送 2 刀加群送 10 刀免费体验 做了一个短信平台(支持全球 OTP / 营销),想听听大家的意见 LiteLLM 接 AWS Bedrock 做了个 Claude API 平台,现在找种子用户, V2EX 用户专属 100 元无门槛优惠券 🚀 Unity2.Ai 公测招募|直达源头,拒绝降智,新用户加群送 10 刀免费体验 大厂国际云 [腾讯、阿里、AWS] 开户充值,长期续费 - V2EX # 抽奖 | 懒猫小龙猫 AI Agent 抽奖活动(第一轮) 落魄前端失业一年多决定帮岳父卖五常大米 国际站阿里云代理商实名企业账号 LingduCloud 零度云,做海外业务这路子其实挺省心! 免实名高速稳定海外服务器 即开即用 单一中转站不稳定,试试这个 1openapi.com - V2EX 既然推广节点全是中转站,我也来发点测试额度 - V2EX 便宜服务器真的能用吗?我用过之后的真实感受 服务器 seo 站群 多 IP 搭建 少 IP 物理机 稳定 诚信 靠谱 - V2EX macOS 上班摸鱼神器 Glanceway 更新(二) - V2EX 十年机房经验 💥 [最高领 $10 测试金] 纯血 Codex Pro 池 + 高智商 Claude!一个越用越稳的 API 中转站 Claude API 官方价一折起,企业级直连稳定接入 “万 1 免 5” a 股券商低佣免五开户,抽一箱汾酒 [6 瓶] ~~ [大笑脸开户] 香港排名第一数字银行 众安银行开户额外返现 300HKD . - V2EX Bitget 钱包,稳定支付 AI 的 U 卡,首笔返现 50%, 结束 4 月 30 号,新用户成功开卡返 3U 香港排名第一数字银行 众安银行开户额外返现 300HKD ! - V2EX [免费领取 1G 测试流量包] 动态住宅 IP | 住宅代理 | 海外 IP | ResidentialIP
[一个“去重”写了 20 种方法?盘点 Python 列表去重的奇技淫巧]
jarryli · 2026-05-01 · via 推广

想起茴香的茴子有四种写法,孔乙己先生是高明的,他如果生在这个时代,就能用不同的思路让 AI 帮他解决问题了。

列表(数组)去重是最常见的算法,非常简单,但不同实现方式背后的差异巨大。AI 时代,可以不手写代码了,但需要知道代码背后的原理,这样才能更好地指导 AI 编程。

最简单的思路

新建列表,遍历原列表,当原列表的元素不在新列表的,则添加到新列表中。

def unique(data):
    # 新建 list
    new_list = []
    for item in data:
        # 原 list 中的项是否存在于新 list 中,不存在则添加。这是 O(n)操作
        if item not in new_list:
            new_list.append(item)
    return new_list

这种写法最直观易懂,但每次 not in 都要遍历整个 new_list,复杂度为 O(n²)。

如何降低复杂度呢?可以从以下角度思考:

  • 哈希集合 / 字典:把查询从 O(n) 可压到 O(1),整体 O(n)
  • 先排序:相同元素两两比较再去重,O(nlogn),但会破坏原顺序
  • 函数式 / 递归:写法上换一种风格,适用不同场景,本质仍是上面的方式

第 1 类:基础循环(方法 1-8 )

策略原理:遍历原数组,直接用双重循环或下标比较找出重复项。每一步判断"是否存在"都是 O(n),整体复杂度 O(n²)。

适用场景:这里主要是展示算法原理,用于教学示例,弄懂编程原理。生产代码不建议使用。

# 方法 1:最基础的线性查找
def unique_v1(data):
    new_list = []
    for item in data:
        # in 在列表上是 O(n) 扫描,整体 O(n²)
        # 该元素不在新 list 则添加
        if item not in new_list:
            new_list.append(item)
    return new_list

# 方法 2:用下标遍历
def unique_v2(data):
    new_list = []
    for i in range(len(data)):
        # 与第 1 种相同,遍历方式换成 range ,复杂度不变
        if data[i] not in new_list:
            new_list.append(data[i])
    return new_list

# 方法 3:列表推导式
def unique_v3(data):
    new_list = []
    # 利用列表推导式的副作用追加元素,写法简化,本质与前面一样
    [new_list.append(i) for i in data if i not in new_list]
    return new_list

# 方法 4:通过元素首次出现位置判断
def unique_v4(data):
    new_list = []
    for i in range(len(data)):
        # data.index(x) 返回 x 在 data 里第一次出现的下标
        # 当前下标恰好等于该值时,说明该元素是首次出现,将首次出现的添加到新 list
        if i == data.index(data[i]):
            new_list.append(data[i])
    return new_list

# 方法 5:原地删除(从右往左扫描)
def unique_v5(data):
    l = len(data)
    while l > 0:
        l -= 1
        i = l
        while i > 0:
            i -= 1
            # 在 [0, l) 区间里寻找与 data[l] 相同的元素
            # 找到就删后面那个,保留前面的
            if data[i] == data[l]:
                del data[l]
                break
    return data
# 修改原列表,空间 O(1)

# 方法 6:原地删除(从左往右扫)
def unique_v6(data):
    l = len(data)
    i = 0
    while i < l:
        j = i + 1
        while j < l:
            # 把 data[i] 后面所有等于它的元素删掉
            if data[i] == data[j]:
                del data[j]
                l -= 1   # 列表变短,长度同步更新
            else:
                j += 1
        i += 1
    return data

# 方法 7:用 try-except 替代 in
def unique_v7(data):
    new_list = []
    for item in data:
        try:
            # index 找不到会抛 ValueError
            new_list.index(item)
        except ValueError:
            # 找不到才追加
            new_list.append(item)
    return new_list
# 实际上不会这么使用——拿异常处理正常的控制流,性能和可读性都吃亏

# 方法 8:双层循环+下标判断
def unique_v8(data):
    new_list = []
    for i in range(len(data)):
        j = 0
        while j <= i:
            # 看 data[i] 在它之前是否出现过
            if data[i] == data[j]:
                # 只有 j == i (前面都没遇到)时才追加
                if i == j:
                    new_list.append(data[i])
                break
            j += 1
    return new_list
# 内层只跑到 i 而非 n ,比较次数约为方法 1 的一半,但渐进复杂度仍是 O(n²)

第 2 类:哈希表(方法 9-12 )

策略原理:利用 dictset 的键( Key )唯一性来记录"已经出现的元素"。哈希结构的查询是 O(1),因此整体降到 O(n)。代价是需要 O(n) 额外内存空间,且元素必须可哈希——数字、字符串、元组都可以,但 list 、dict 这类可变对象不行。

适用场景:日常项目的首选。需要保留原顺序时尤其合适,因为一边查重一边按原序写入结果。

# 方法 9:set 配合 list——工程最常见写法
def unique_v9(data):
    seen = set()        # set 用于 O(1) 判重
    result = []         # list 用于保持原顺序
    for item in data:
        if item not in seen:
            seen.add(item)
            result.append(item)
    return result

# 方法 10:dict.fromkeys()——最佳版本,实际使用首选
def unique_v10(data):
    # dict 自 Python 3.7 起保持插入顺序
    # fromkeys 会自动用相同 key 覆盖,从而完成去重
    return list(dict.fromkeys(data))

# 方法 11:filter + 列表,函数式风格
def unique_v11(data):
    seen = []
    # 内部函数
    def check(item):
        # 闭包捕获 seen
        # 注意 seen 是 list ,in 仍是 O(n),整体仍是 O(n²)
        if item not in seen:
            seen.append(item)
            return True
        return False
    return list(filter(check, data))
# 函数式风格,但不纯粹,seen 类型选错了,这里只是为了展示写法

# 方法 12:filter + 字典,由 list 改为 dict ,仍然不是纯函数式
def unique_v12(data):
    obj = {}
    def check(item):
        # 用 dict 替代上面的 list ,查询变成 O(1)
        if obj.get(item) is None:
            obj[item] = item
            return True
        return False
    return list(filter(check, data))

第 3 类:集合与排序(方法 13-16 )

策略原理:将list直接转 set,或者通过 sort() 让相同元素挨在一起再去重,从而简化查找逻辑。两种思路都不再保留原有顺序。集合方式 O(n),排序方式 O(nlogn),且要求元素可比较。

适用场景:不关心顺序、只关心结果集合的场合,例如统计去重数量、做集合运算、把列表当作"无序集合"使用。

# 方法 13:set 直接转列表,常见用法
def unique_v13(data):
    # 哈希集合天然不重复
    return list(set(data))
# 写法最短,但顺序会被打乱

# 方法 14:map + filter 组合
def unique_v14(data):
    seen = []
    def mark(item):
        # 第一次见到返回元素本身,后续返回 None
        if item not in seen:
            seen.append(item)
            return item
        return None
    # 先 map 标记,再 filter 把 None 去掉
    return list(filter(lambda x: x is not None, map(mark, data)))
# 函数式风格,但 seen 用 list 仍是 O(n²)

# 方法 15:先排序再相邻去重(从右往左删)
def unique_v15(data):
    data.sort()  # 排序后,相同元素会聚到一起
    l = len(data)
    while l > 0:
        l -= 1
        # 相邻两两比较,相同就删后面那个
        if l > 0 and data[l] == data[l-1]:
            del data[l]
    return data
# 复杂度由 sort 决定,O(nlogn);元素需要可比较

# 方法 16:先排序再相邻去重(从左往右删)
def unique_v16(data):
    data.sort()
    l = len(data) - 1
    i = 0
    while i < l:
        if data[i] == data[i+1]:
            del data[i]   # 删当前,i 不前进;同时长度减一
            i -= 1
            l -= 1
        i += 1
    return data

第 4 类:函数式与递归(方法 17-20 )

策略原理:用 reduce、外部库或递归换一种表达方式。reduce 配合元组累加器可以做到 O(n),但写法比直接 for 循环晦涩;递归则吃调用栈、numpy 需要库依赖。

适用场景:numpy 适合大规模数值数据;其余几种主要用于练习函数式或递归思维,工程上一般直接用第 2 类。

# 方法 17:reduce + 元组累加器(函数式风格但能跑到 O(n))
import functools

def unique_v17(data):
    def foo(acc, item):
        # 累加器是一个元组 (result, seen)
        # result 保留首次出现的顺序,seen 用集合实现 O(1) 判重
        result, seen = acc
        if item in seen:
            return (result, seen)
        # 这里直接修改累加器内部的 list 和 set
        # 严格的纯函数式应返回新对象 (result + [item], seen | {item})
        # 但那样每步都新建列表/集合,复杂度退回到 O(n²)
        # 在 reduce 内做"受控副作用",换取 O(n) 的性能
        seen.add(item)
        result.append(item)
        return (result, seen)

    # 初始累加器是空列表+空集合,最后取 [0] 即得到去重结果
    return functools.reduce(foo, data, ([], set()))[0]
# O(n);保序;本质是用 reduce 重写了方法 9 的循环

# 方法 18:调用 numpy.unique
def unique_v18(data):
    import numpy as np
    # numpy 底层用 C 实现的排序+相邻去重
    return list(np.unique(np.array(data)))
# O(nlogn);不保序;适合大规模数值数据

# 方法 19:递归+原地删除
def unique_v19(data, length=None):
    # 递归退出条件
    if length is None:
        length = len(data)
    if length <= 1:
        return data

    last_idx = length - 1
    # 看末尾元素是否在前面出现过
    is_repeat = False
    for i in range(last_idx):
        if data[i] == data[last_idx]:
            is_repeat = True
            break

    # 重复则删除
    if is_repeat:
        del data[last_idx]

    # 递归调用,处理前 length-1 项
    return unique_v19(data, length - 1)
# 递归深度 = n ,大数据会栈溢出,仅作学习用

# 方法 20:递归+拼接返回(不修改原列表)
# 递归自后往前逐个调用,当长度为 1 时终止。与上一个递归不同,这里将不重复的项目作为结果拼接起来
def unique_v20(data, length=None):
    if length is None:
        length = len(data)
    if length <= 1:
        return data

    last_idx = length - 1
    last_item = data[last_idx]

    is_repeat = False
    for i in range(last_idx):
        if data[i] == last_item:
            is_repeat = True
            break

    # 末尾元素重复就丢弃,否则拼到结果末尾
    result = [] if is_repeat else [last_item]
    # 切片 + 拼接都会产生新列表,空间开销大
    return unique_v20(data[:last_idx], length - 1) + result
# 演示如何用递归构造结果,工程上没有实用价值

这么多实现方式,如何选择?

类别 时间复杂度 是否保序 主要场景
基础循环 O(n²) 教学、极小规模
哈希表 O(n) 日常项目首选
集合 / 排序 O(n) / O(nlogn) 不在意顺序
函数式 / 递归 视实现而定 看实现 学习、特定场景

实际项目里怎么选

绝大多数情况一行就够:

# 保序、O(n)、对所有可哈希类型有效,Python 3.7+ 自带
result = list(dict.fromkeys(data))

不在意顺序:

result = list(set(data))

数据量很大且都是数值:

import numpy as np
result = list(np.unique(data))

带逻辑干预的去重

前面所有方法都把"重复的元素"直接丢掉。但实际工作里经常遇到这样的情况:遇到重复时不能简单丢弃,要根据某个条件做处理。比如:

  • id 去重,但要保留分数最高的那条记录
  • 去重的同时累加重复次数(即频次统计)
  • 数值在某个区间内才参与去重,区间外原样保留

这类需求 setdict.fromkeys 都没法直接表达,需要把"判重"和"处理"两步拆开来写。

def unique_with_rule(data, key=None, on_duplicate=None):
    """
    带逻辑干预的去重。

    key: 可哈希的去重键,默认拿元素本身
    on_duplicate: 遇到重复时如何处理 (旧值, 新值) -> 新的"代表值"
                  返回 None 时保持旧值不变(即等同于丢弃新值)
    """
    if key is None:
        key = lambda x: x

    chosen = {}     # 键 -> 当前选中的元素
    order  = []     # 记录键首次出现的顺序,保证保序

    for item in data:
        k = key(item)
        if k not in chosen:
            chosen[k] = item
            order.append(k)
        elif on_duplicate is not None:
            # 遇到重复时由调用方决定如何合并
            merged = on_duplicate(chosen[k], item)
            if merged is not None:
                chosen[k] = merged

    return [chosen[k] for k in order]

例 1 ,按 id 去重,保留分数最高的:

students = [
    {'id': 1, 'name': '张三', 'score': 90},
    {'id': 1, 'name': '张三', 'score': 95},   # 同 id ,分数更高
    {'id': 2, 'name': '李四',   'score': 99},
]
result = unique_with_rule(
    students,
    key=lambda x: x['id'],
    on_duplicate=lambda old, new: new if new['score'] > old['score'] else old,
)
# [{'id':1,'score':95,...}, {'id':2,'score':99,...}]

例 2 ,去重的同时统计每个值的出现次数:

from collections import Counter

data = ['A', 'B', 'A', 'C', 'B', 'A']
# Counter 本身就是"键->计数",遍历一次即可完成统计
counts = Counter(data)
# Python 3.7+ 起 dict / Counter 保留插入顺序,因此 keys 即首次出现顺序
unique_keys = list(counts.keys())
# unique_keys = ['A', 'B', 'C']
# counts      = {'A': 3, 'B': 2, 'C': 1}

例 3 ,区间过滤——只对 [0, 50] 区间内的值去重,区间外的原样保留:

data = [5, 12, 5, 100, 12, 200]
seen = set()
result = []
for x in data:
    if 0 <= x <= 50:
        # 区间内才参与去重
        if x in seen:
            continue
        seen.add(x)
    # 区间外或首次出现,都保留
    result.append(x)
# [5, 12, 100, 200]

这三个例子是同一种思路:把判重与业务规则分开。判重用哈希结构保证 O(n),规则部分留给回调或显式分支处理,这样既不丢性能,又能容纳各种业务变化。


AI 时代,程序员不一定要手写代码,但一定要懂得编程思路,这样才能更好地指导 AI 。

更多算法

不同语言算法实现:https://github.com/microwind/algorithms

AI 编程知识库:https://microwind.github.io