You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python列表交集去重代码未达预期,原因何在?

问题:列表推导式求无重复交集失败,结果仍有重复元素

我是编程初学者,若问题过于基础还请见谅。我尝试编写代码生成两个随机列表,并通过列表推导式求出无重复的交集,但代码未达到预期效果。

代码如下:

import random
a = random.choices(range(0, 10), k = 7) 
b = random.choices(range(0, 10), k = 7) 
print(a) 
print(b) 
c = []
c = [i for i in a if i in b if i not in c]

部分运行结果如下:

a = [1, 4, 1, 7, 2, 3, 8] b = [5, 6, 4, 9, 4, 4, 1] c = [1, 4, 1]

a = [7, 3, 8, 4, 7, 5, 3] b = [3, 3, 7, 8, 1, 4, 7] c = [7, 3, 8, 4, 7, 3]

显然结果中包含重复元素,请问这是为什么?难道列表c不会在每次循环后更新,从而检查并排除重复元素吗?


原因分析

列表推导式的执行逻辑是:先遍历所有元素、计算所有条件,最后一次性把结果赋值给变量。你在推导式里写的i not in c,这里的c始终是初始化时的空列表[]——推导式运行全程,c都不会被实时更新,所以每次判断i not in c时,都是在和空列表对比,自然拦不住后续出现的重复元素。

拿第一次运行的例子来说:

  • 遍历第一个1:1 in b为真,1 not in []也为真,加入结果;
  • 遍历4:同理加入结果;
  • 遍历第二个1:此时c还是空列表,1 not in []依然为真,所以又被加进去了。

解决方案

方法1:用集合处理(最简单高效)

集合天生不允许重复元素,求交集的操作也很直接:

import random
a = random.choices(range(0, 10), k = 7) 
b = random.choices(range(0, 10), k = 7) 
print(a) 
print(b) 
# 转集合去重后求交集,再转回列表
c = list(set(a) & set(b))

如果需要保留元素在a中首次出现的顺序,可以改用循环+辅助集合:

import random
a = random.choices(range(0, 10), k = 7) 
b = random.choices(range(0, 10), k = 7) 
print(a) 
print(b) 
c = []
seen = set()
for num in a:
    if num in b and num not in seen:
        c.append(num)
        seen.add(num)

方法2:改进列表推导式(借助辅助集合)

如果一定要用列表推导式,可以引入一个辅助集合来记录已添加的元素:

import random
a = random.choices(range(0, 10), k = 7) 
b = random.choices(range(0, 10), k = 7) 
print(a) 
print(b) 
seen = set()
c = [num for num in a if num in b and not (num in seen or seen.add(num))]

这里利用了seen.add(num)返回None的特性:如果num不在seen里,num in seen为假,就会执行seen.add(num),同时not None为真,将num加入列表;如果num已经在seen里,num in seen为真,整个条件为假,不会加入重复元素。


内容的提问来源于stack exchange,提问作者José Alberto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 02:37:36