优化从大文件中删除重复行

时间:2014-11-22 00:10:26

标签: python

如何优化此代码。我想从文件中删除重复的行,但是如果效率低,请考虑使用set,并限制我可以解析的文件大小。

file = open("sample.txt")

output = []
alreadyseen = set()    

while True:
    lines = file.readlines(100000)
    if not lines:
        break
    for line in lines:
        pass # do something
        if line not in alreadyseen:
            output.append(line)
            alreadyseen.add(line)
    print(output)   

2 个答案:

答案 0 :(得分:1)

写入临时文件以避免在列表中存储所有行,然后重新打开这两个文件并使用file1的内容更新file2

alreadyseen = set()
with open(file_1) as f1, open(file_2, "w") as f2:
    while True:
        lines = f1.readlines(100000)
        if not lines:
            break
        for line in lines:
            pass # do something
            if line not in alreadyseen:
                f2.write(line)
                alreadyseen.add(line)

with open(file1, "w") as f1, open(file_2) as f2:
    for line in f2:
        f1.write(line)

答案 1 :(得分:1)

您的算法很可能是执行此操作的最快方法,但正如您所说,它将受到您可以在内存中容纳的行数的限制。有一些技术可以缓解这个问题,并允许您处理更大的文件。

第一种是一次只读写一行。由于您单独处理它们,因此无需一次读取100000块,当然没有理由将所有独特结果保存在单个字符串中。一次读写一行,以减少浪费。

第二种是用加密哈希替换更长的字符串。无论线路本身有多长,哈希都是固定大小的。如果您担心两个字符串产生相同散列的可能性,请不要 - 使用足够大的散列,两个产生相同散列的字符串的概率低于允许两个不同字符串的RAM故障的概率比较平等,即使考虑到birthday paradox

结合两种方法看起来像这样:

import hashlib

sha256 = hashlib.sha256()
alreadyseen = set()
with open("sample.txt") as file:
    for line in file:
        pass # do something
        key = line if len(line) < 32 else sha256(line)
        if key not in alreadyseen:
            alreadyseen.add(key)
            print(line)