簡體   English   中英

實施外部合並排序

[英]Implementing an external merge sort

我正在嘗試學習Python,並且正在使用帶有int的輸入文件進行外部合並排序。 我正在使用heapq.merge,我的代碼幾乎可以正常工作,但是它似乎將我的行作為字符串而不是整數進行排序。 如果我嘗試轉換為整數,則寫入行將不接受數據。 誰能幫我找到替代方案? 另外,我是否認為這可以使我對文件進行排序,使其大於內存(如果有足夠的磁盤空間),是否正確

import itertools
from itertools import islice
import tempfile
import heapq

#converts heapq.merge to ints
#def merge(*temp_files):
#    return heapq.merge(*[itertools.imap(int, s) for s in temp_files])

with open("path\to\input", "r") as f:
    temp_file = tempfile.TemporaryFile()
    temp_files = []
    elements = []
    while True:
        elements = list(islice(f, 1000))
        if not elements:
           break
        elements.sort(key=int)
        temp_files.append(elements)
        temp_file.writelines(elements)
        temp_file.flush()
        temp_file.seek(0)
        with open("path\to\output", "w") as output_file:
            output_file.writelines(heapq.merge(*temp_files))

默認情況下,您的元素被讀取為字符串,您必須執行以下操作:

elements = list(islice(f, 1000))
elements = [int(elem) for elem in elements]

以便將它們解釋為整數。

這也意味着您在編寫時需要將它們轉換回字符串,例如:

temp_file.writelines([str(elem) for elem in elements])

除此之外,您還需要將元素再次轉換為int以進行最終合並。 在您的情況下,您可能想取消注釋您的merge方法(然后將結果再次轉換回字符串,方法同上)。

您的代碼對我來說沒有多大意義( temp_files.append(elements)嗎?是否在循環中合並?),但是這是一種以數字方式合並文件的方式:

import heapq
files = open('a.txt'), open('b.txt')
with open('merged.txt', 'w') as out:
    out.writelines(map('{}\n'.format,
                       heapq.merge(*(map(int, f)
                                     for f in files))))

首先, map(int, ...)將每個文件的行轉換為int。 然后,這些將與heapq.merge合並。 然后map('{}\\n'.format用換行符將每個整數重新轉換成字符串。然后writelines寫入這些行。換句話說,您已經很接近了,只需要在寫入之前將int轉換回字符串即可他們。

編寫它的另一種方法(有些可能會更清楚):

import heapq
files = open('a.txt'), open('b.txt')
with open('merged.txt', 'w') as out:
    int_streams = (map(int, f) for f in files)
    int_stream = heapq.merge(*int_streams)
    line_stream = map('{}\n'.format, int_stream)
    out.writelines(line_stream)

在任何情況下,如果您使用的是Python 2,請itertools.imap使用itertools.imap ,否則它將立即將整個文件讀入內存。 在Python 3中,您可以只使用法線map

是的,如果操作正確,這將使您可以用很少的內存對巨大的文件進行排序。

你正在做粿 ,這將增加很多runtimeComplexity的環路內合並。 更好地將文件句柄存儲到spearate列表中並執行Kway合並

您也不必刪除並添加新行,只需根據數字對其進行排序。

排序(temp_files,key = lambda no:int(no.strip()))

其余的一切都很好。

https://github.com/melvilgit/external-Merge-Sort/blob/master/README.md

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM