与使用python的大型文件B相比,从大型文件A中查找唯一行的最快方法是什么?

与使用python的大型文件B相比,从大型文件A中查找唯一行的最快方法是什么?,python,compare,Python,Compare,我得到了包含300000多行的txt文件A和包含600000多行的txt文件B。现在我要做的是逐行筛选文件A,如果该行没有出现在文件B中,那么它将被附加到文件C中 好吧,问题是如果我像上面所说的那样编程,完成所有的工作确实需要很多时间。有没有更好的方法呢?我对python一无所知,但是:把文件a按特定顺序排序怎么样?然后,您可以逐行浏览文件B并进行二进制搜索-效率更高。这应该非常快: with open("a.txt") as a: with open("b.txt") as b:

我得到了包含300000多行的txt文件A和包含600000多行的txt文件B。现在我要做的是逐行筛选文件A,如果该行没有出现在文件B中,那么它将被附加到文件C中


好吧,问题是如果我像上面所说的那样编程,完成所有的工作确实需要很多时间。有没有更好的方法呢?

我对python一无所知,但是:把文件a按特定顺序排序怎么样?然后,您可以逐行浏览文件B并进行二进制搜索-效率更高。

这应该非常快:

with open("a.txt") as a:
    with open("b.txt") as b:
        with open("c.txt", "w") as c:
            c.write("".join(set(a) - set(b)))
请注意,这将忽略A或B中的任何订单。如果您确实需要保留A的订单,您可以使用以下命令:

with open("a.txt") as a:
    with open("b.txt") as b:
        with open("c.txt", "w") as c:
            b_lines = set(b)
            c.write("".join(line for line in a if not line in b_lines))

将文件B中的所有行读入一组:


600k+并没有那么多数据…

你能在内存中保存B吗?如果是这样,读取文件B并创建一个包含所有行的索引。然后逐行阅读,检查每一行是否出现在索引中

with open("B") as f:
    B = set(f.readlines())

with open("A") as f:
    for line in f.readlines():
        if line not in B:
           print(line)

可能是有用的,这几乎肯定会比任何简单的设计更有效地检查一行是否在另一个文件中。同样,如果您使用*nix,diff工具也可以做到这一点。如果您使用*nix平台,我建议您使用批处理来完成此操作,您可以从python调用bash命令,类似于diff-suppress common lines-y一种有用的数量级计算:一个字符是一个字节,一行是75个字符,因此,将整个文件读入内存大约需要600000*75/1000000=45MB。现在这很平常,所以你可以把这两个文件读入内存,然后用这种方式比较它们。当然,如果你处理的文件要大得多,那你就做不到。很好+1.我认为这应该被接受为官方答案,除非c的顺序需要与a相同。@nightcracker:非常感谢,这确实是闪电般的快!干杯@尚恩·斯蒂芬·菲南:如果我的答案解决了你的问题,考虑把它标记为点击我的答案左边的Tigbox。为什么不以更灵活的方式来做它,不要求你在内存中存储两个大文件,以及三个大文件集,两个文件由一个文件组成,一个是它们之间的区别?另外,您还可以使用上下文管理器,而不是显式关闭文件。@Tadeck,您这个老古董,趁它便宜的时候抓取您的8G内存吧!只会越来越便宜。注意,作为一个内存占用者,特别是对于一次性脚本来说,已经不像以前那么糟糕了。不需要列表理解,该文件是一个逐行生成器。所以你可以调用setfile_b@jamylak,对,除非您想保持顺序:C中的行与A中的行顺序相同,但B中也有缺失的行。无论您如何构造集合,它都不会保持顺序。@jamylak,没错!这就是我迭代A的原因。这保持了C wrt A中的顺序。我只是指创建集合bline。如果你给它传递一个列表,它必须先把它加载到内存中,但是如果你给它传递一个生成器,它会逐行创建一个集合,这样效率更高。
with open("B") as f:
    B = set(f.readlines())

with open("A") as f:
    for line in f.readlines():
        if line not in B:
           print(line)