【问题标题】:merge multiple sorted big files--python合并多个排序的大文件--python
【发布时间】:2015-09-15 07:43:08
【问题描述】:

任务是合并排序两个大文件(内存放不下)。经过一番研究,使用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 利用率。有什么建议吗?

【问题讨论】:

  • heapq.merge 仅适用于已排序的输入数据。您的数据文件是否已经排序?
  • @SamuelO'Malley 是的!
  • 这是一道作业题吗?如果是这样,我强烈建议您尝试在不使用 heapq.merge 的情况下自己实现这一点,因为它不是很困难,并且可以很容易地跳过空白行。
  • @SamuelO'Malley,明白了。我将在没有 heaq.merge 的情况下实现它,然后发布它。之后,你能回答这个问题吗?我对使用 heaq.merge 也很感兴趣。
  • 那么我会给出 heapq.merge 的答案,如果它不起作用请告诉我。

标签: python algorithm sorting merge mergesort


【解决方案1】:

如果您想在跳过空行时使用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))

另外,这个问题听起来很像一个家庭作业问题(如果不是的话,我会强烈建议您自己实现合并逻辑,因为这是一个有趣的问题。

【讨论】:

  • 非常感谢!是的,实现合并逻辑很有趣。我正在做。 :-)
猜你喜欢
  • 2016-04-19
  • 1970-01-01
  • 2017-07-13
  • 2014-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-13
  • 2014-12-02
相关资源
最近更新 更多