#!/usr/bin/env python3
import contextlib
import heapq
import sys
from itertools import groupby
from tempfile import TemporaryFile
from operator import itemgetter
def uniq(sorted_items):
return map(itemgetter(0), groupby(sorted_items))
sorted_files = []
with contextlib.ExitStack() as stack:
# sort lines in batches, write intermediate result to temporary files
nbytes = 1 << 15 # read ~nbytes at a time
for lines in iter(lambda f=sys.stdin.detach(): f.readlines(nbytes), []):
lines.sort()
file = stack.enter_context(TemporaryFile('w+b')) #NOTE: file is deleted on exit
file.writelines(uniq(lines)) # write sorted unique lines
file.seek(0) # rewind, to read later while merging partial results
sorted_files.append(file) #NOTE: do not close the temporary file, yet
# merge and write results
sys.stdout = sys.stdout.detach() # suppress ValueError: underlying buffer has been detached
sys.stdout.writelines(uniq(heapq.merge(*sorted_files)))
从列表中删除重复项的最快和最简单的方法是将其转换为集合。set() 集合构造函数接受任何可迭代对象,包括文件描述符。之后,只剩下将集合转换回字符串并将其写入另一个文件:
要打印在命令行或标准输入中指定的文件中给出的唯一电子邮件:
例子:
或者:
即使行中存在/不存在不可见空间,代码也能正常工作。例如,文件中的最后一行可能有也可能没有换行符——结果仍然是正确的。
存在
set()
导致结果以随机顺序打印,每次运行都可能发生变化。要模拟sort -u emails.txt
,您可以使用groupby(sorted())
:用法相同:输入从文件或标准输入中读取,输出打印到标准输出。
对于电子邮件的情况,这不是必需的,但一般来说,要仅打印内存中放不下的大文件中的唯一行
LC_ALL=C sort -u < input
,Python 等效项是:例子:
在这种情况下,输入仅来自标准输入,字符串作为字节序列进行比较(假设所有字符串都以换行符结尾)。
相关问题:使用 Python 对文本文件进行排序。