在python中排序并获取唯一的文件行

时间:2013-11-04 09:19:58

标签: python command-line unique

我总是使用这个命令行来排序并获得uniq行,即使对于大文件(超过500,000行)它也可以作为魅力

sort filename.txt | uniq | sponge filename.txt

最短的等效python代码将是

f = open("filename.txt", "r")
lines = [line for line in f]
lines = lines.sort()
lines = set(lines)

但当然这是不可扩展的,因为内存约束和在python中编写可伸缩代码需要时间 ,所以我想知道python中最短的等效代码(包)是什么

4 个答案:

答案 0 :(得分:5)

你不需要在python中进行排序,因为即使没有排序,set也会处理唯一性。

f = open("filename.txt", "r")
lines = set(f.readlines())

shell sort命令也会将行加载到内存中,因此使用它不会为您节省任何内存。如果你有非常大的文件或坚持不使用额外的内存,你可以尝试一些疯狂的技巧,如下所示:http://neopythonic.blogspot.in/2008/10/sorting-million-32-bit-integers-in-2mb.html

答案 1 :(得分:3)

有一个迭代器可以执行排序操作。让我们制作一个模仿uniq,只产生不等于前一行的行:

def uniq(iterator):
    previous = float("NaN")  # Not equal to anything
    for value in iterator:
        if previous != value:
            yield value
            previous = value

现在你可以做同样的事情:

with open('/path/to/filename') as f:
    for line in uniq(sorted(f)):
        print(line)

BUt sorted(和shell的排序)无论如何都必须存储所有东西(如果文件中的最后一行应该先输出怎么办),所以它比使用set(f)而不是uniq(sorted(f))更糟糕。

答案 2 :(得分:1)

这是一个较短的例子:

with open("filename.txt", 'r') as f:
    lines = set(f)

另外,有一点需要注意,在这种情况下,一次只有 一行 会被加载到内存中。原因是上面的代码相当于:

lines = set()
f = open("filename.txt", 'r')
for line in f: # now f works as a generator of lines, reading only one line at a time
     lines.add(line)

答案 3 :(得分:1)

使用python中的shell命令:

import os
os.system("sort filename.txt | uniq | sponge filename.txt")