Python文本去重是数据处理场景中非常常见的需求,无论是日志清洗、爬虫数据去重还是用户内容去重,都需要高效可靠的方案。不同的去重场景对内存占用、去重顺序、处理速度的要求不同,需要针对性选择实现方式。

基础去重方案:基于set数据结构
set是Python内置的无序不重复元素集合,利用这个特性可以快速实现文本去重,适合对去重后顺序没有要求的场景。
实现逻辑很简单,直接将文本列表转换为set,再转回列表即可:
# 原始文本列表 text_list = ["苹果", "香蕉", "苹果", "橙子", "香蕉", "葡萄"] # 使用set去重 deduplicated_set = set(text_list) # 转回列表 result = list(deduplicated_set) print(result)
这种方案的时间复杂度是O(n),处理速度很快,但缺点是无法保留原始文本的顺序,因为set是无序的。如果需要保留顺序,可以使用这种方法:
text_list = ["苹果", "香蕉", "苹果", "橙子", "香蕉", "葡萄"]
seen = set()
result = []
for text in text_list:
if text not in seen:
seen.add(text)
result.append(text)
print(result)
大文本去重方案:基于哈希校验
当处理的文本数量非常大,或者单个文本长度很长时,直接存储完整文本会占用大量内存。这时候可以使用hashlib模块计算文本的哈希值,用哈希值代替完整文本进行去重判断。
常用的哈希算法是MD5,碰撞概率极低,适合大多数场景:
import hashlib
def get_text_hash(text):
# 计算文本的MD5哈希值
md5 = hashlib.md5()
md5.update(text.encode("utf-8"))
return md5.hexdigest()
text_list = ["这是一段很长的文本内容", "这是另一段文本内容", "这是一段很长的文本内容"]
seen_hash = set()
result = []
for text in text_list:
text_hash = get_text_hash(text)
if text_hash not in seen_hash:
seen_hash.add(text_hash)
result.append(text)
print(result)
这种方案只需要存储哈希值,内存占用会大幅降低,处理百万级文本时优势明显。但要注意如果文本存在极细微的差异,哈希值会完全不同,适合完全重复文本的去重场景。
复杂文本去重:基于相似度判断
如果需求不是完全重复文本去重,而是相似文本去重,比如"今天天气很好"和"今天天气非常不错"需要判定为重复,就需要用到文本相似度算法。这里以简单的编辑距离为例:
def levenshtein_distance(s1, s2):
# 计算两个字符串的编辑距离
len1, len2 = len(s1), len(s2)
dp = [[0] * (len2 + 1) for _ in range(len1 + 1)]
for i in range(len1 + 1):
dp[i][0] = i
for j in range(len2 + 1):
dp[0][j] = j
for i in range(1, len1 + 1):
for j in range(1, len2 + 1):
if s1[i-1] == s2[j-1]:
dp[i][j] = dp[i-1][j-1]
else:
dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1
return dp[len1][len2]
text_list = ["今天天气很好", "今天天气非常不错", "明天会下雨"]
result = []
threshold = 2 # 编辑距离阈值,小于该值判定为相似
for text in text_list:
is_similar = False
for existing in result:
if levenshtein_distance(text, existing) <= threshold:
is_similar = True
break
if not is_similar:
result.append(text)
print(result)
这种方案适合需要模糊去重的场景,但计算量比前两种方案大很多,处理大量文本时性能会下降,需要根据实际需求权衡。
不同方案对比
以下是几种常见去重方案的对比,方便开发者选择:
| 方案类型 | 时间复杂度 | 内存占用 | 是否保留顺序 | 适用场景 |
|---|---|---|---|---|
| 基础set去重 | O(n) | 中 | 否 | 小批量完全重复文本,不要求顺序 |
| 有序set去重 | O(n) | 中 | 是 | 小批量完全重复文本,要求保留原顺序 |
| 哈希去重 | O(n) | 低 | 可自定义 | 大批量完全重复文本,内存有限场景 |
| 相似度去重 | O(n²) | 中 | 是 | 模糊重复文本去重,文本量较小场景 |
注意事项
- 处理文本前建议统一编码格式,避免因为编码不同导致重复判断错误
- 如果文本包含大量特殊字符,去重前可以做清洗处理,比如去除空格、标点等
- 哈希去重时如果对安全性要求高,可以使用sha256代替md5,降低哈希碰撞概率
- 处理超大文件时,可以逐行读取文本,避免一次性加载全部内容到内存
实际开发中可以根据文本规模、去重精度、顺序要求等维度选择合适的方案,也可以组合多种方案实现更高效的去重逻辑。