任务是合并排序两个大文件(不能适合内存)。在做了一点研究之后,使用heapq.merge
import heapq
import contextlib
filenames=('data1.txt', 'data2.txt')
with contextlib.ExitStack() as stack:
files = [stack.enter_context(open(fn)) for fn in filenames]
with open('data', 'w') as f:
f.writelines(heapq.merge(*files))
问题是如何处理文件中的空行。例如:
DATA1.TXT:
苹果
亚马逊
谷歌
Data2.txt:
您好
今天
世界
Output:
apple
amazon
google
hello
today
world
我不使用heapq.merge的答案:
def read_non_empty_line(input):
while True:
line = input.readline()
if line == "":
return ""
if line.isspace() == False:
return line.strip()
#return line
def combine_sorted_files(file1, file2, output):
read_file1, read_file2 = True, True
with open(output,'w') as output_file:
with open(file1,'r') as input_file1:
with open(file2,'r') as input_file2:
while True:
if read_file1:
line1 = read_non_empty_line(input_file1)
if read_file2:
line2 = read_non_empty_line(input_file2)
if line1 == "" or line2 == "":
break
read_file1, read_file2 = False, False
if line1 < line2:
smaller = line1
read_file1 = True
else:
smaller = line2
read_file2 = True
output_file.write(smaller+"\n\n")
while line1 != "":
output_file.write(line1+"\n\n")
line1 = read_non_empty_line(input_file1)
while line2 != "":
output_file.write(line2+"\n\n")
line2 = read_non_empty_line(input_file2)
此问题还要求优化内存和CPU利用率。有什么建议吗?
答案 0 :(得分:3)
如果要在跳过空白行时使用heapq.merge
,可以创建自己的生成器函数来处理跳过逻辑:
def iterate_non_blank_lines(file_iterator):
for line in file_iterator:
if line != "":
yield line
注意:我只是检查了空行,但您可以在此处轻松使用正则表达式来跳过仅包含空格的行。
然后可以修改您的代码以使用此生成器:
filenames=('data1.txt', 'data2.txt')
with contextlib.ExitStack() as stack:
files = [iterate_non_blank_lines(stack.enter_context(open(fn))) for fn in filenames]
with open('data', 'w') as f:
f.writelines(heapq.merge(*files))
此外,这个问题听起来很像一个家庭作业问题(如果不是,那就是app),我强烈建议您自己实施合并逻辑,因为这是一个有趣的问题。