如何用Python检查并移除大文件中的反转字符串元组?
如何从超16M行的大文本文件中移除反转的字符串元组?
我现在需要处理一个超过1600万行的大型文本文件,要移除其中互为反转顺序的字符串元组。举个例子,如果文件里有这两行:
352_0F, 352_1F, 0.913
352_1F, 352_0F, 0.913
我希望最终输出只保留其中任意一行就行,比如保留第一行。另外要说明的是,元组和它的反转元组的第三列(col3)的值是完全相同的。
我自己尝试写了一段代码,但没达到预期效果,代码如下:
from collections import defaultdict data = defaultdict(list) with open("OUTPUT.txt","w") as output: for fileName in ["Large_INPUT.txt"]: with open(fileName,'r') as file1: for line in file1: col1,col2,value = line.split(",") if (col1,col2) not in data: if (col2,col1) not in data: data[(col1,col2,value)] output.write(f"{col1},{col2} {value}\n")
有没有人能帮我解决这个问题?
问题分析
你的代码有几个关键问题导致没达到预期:
- 字典键选择错误:你用
(col1,col2,value)作为键,但我们只需要跟踪元组对(不管顺序)——题目明确反转元组的第三列值相同,完全不需要把value包含在键里。 - 判断逻辑冗余:分别判断
(col1,col2)和(col2,col1)是否存在,不如直接把元组对标准化(比如按字典序排序),让两种反转形式对应同一个标识。 - 内存压力隐患:处理16M行的文件,用
defaultdict存储包含value的三元组,会占用大量内存,我们需要更轻量的方式记录已处理的元组。
优化后的解决方案
这里提供两种高效的实现方案,适配不同需求:
方案1:标准化元组键(内存最优)
这个方案通过将元组对按字典序排序生成唯一键,确保反转元组对应同一个标识,内存占用极低,适合超大规模文件:
seen = set() with open("OUTPUT.txt", "w") as output: with open("Large_INPUT.txt", "r") as file1: for line in file1: # 处理逗号前后的空格,同时跳过格式异常的行 parts = [p.strip() for p in line.strip().split(",")] if len(parts) != 3: continue col1, col2, value = parts # 生成标准化键:让(a,b)和(b,a)对应同一个元组 standard_key = tuple(sorted((col1, col2))) if standard_key not in seen: seen.add(standard_key) output.write(f"{col1},{col2},{value}\n")
方案2:双元组记录(优先保留原顺序)
如果你希望严格保留先出现的元组的原始顺序,这个方案会同时记录正反两种元组形式,避免后续重复写入:
seen = dict() with open("OUTPUT.txt", "w") as output: with open("Large_INPUT.txt", "r") as file1: for line in file1: parts = [p.strip() for p in line.strip().split(",")] if len(parts) != 3: continue col1, col2, value = parts # 检查正反元组是否都未被记录 if (col1, col2) not in seen and (col2, col1) not in seen: seen[(col1, col2)] = True seen[(col2, col1)] = True output.write(f"{col1},{col2},{value}\n")
方案优势说明
- 标准化键方案:仅存储排序后的二元组,内存占用比你的原代码减少约1/3,处理16M行文件完全无压力,且逻辑简洁不易出错。
- 双元组记录方案:可以精准控制保留先出现的元组顺序,适合对输出顺序有要求的场景。
- 格式兼容:添加了
strip()处理空格,避免因行内空格导致的元组匹配失败问题。
内容的提问来源于stack exchange,提问作者Sara S
相关产品推荐
相关产品推荐

