-1

根据第二个字段对文件的内容进行排序,例如

输入文件:

Jervie,12,M

Jaimy,11,F

Tony,23,M

Janey,11,F

输出文件:

Jaimy,11,F

Janey,11,F

Jervie,12,M

Tony,23,M

我们需要使用外部排序。
输入文件的大小可以为 4GB。内存为 1GB。

我使用了它,但它不起作用,因为它将所有内容都视为int. 我也怀疑与外部排序的每一轮中的缓冲区大小有关。如何决定呢?

这仅使用整数对文件进行排序。

file = open("i2.txt","r")
temp_files = []
e = []
while True:
    temp_file = tempfile.TemporaryFile()
    e = list(islice(file,2))
    if not e:
        break
    e.sort(key=lambda line: int(line.split()[0]))
    temp_file.writelines(e)
    temp_files.append(temp_file)
    temp_file.flush()
    temp_file.seek(0)
file.close()

with open('o.txt', 'w') as out:
    out.writelines(imap('{}\n'.format, heapq.merge(*(imap(int, f) for f in temp_files))))
out.close()

我可以创建按第二个字段排序的临时文件,但是如何基于此合并它们?

4

2 回答 2

0

我用以下代码做到了:将大文件分成较小的文件。这里假设最多可以读取 4 行。所以我最初将文件分成4行并将它们排序并写入临时文件。然后从每个文件中成对读取这些文件 2 行并将它们合并。不处理角落案件,但是,这应该是其他人思考的开始。

f = open("i1.txt", "r")
temp_files = []
e = []
while True:
    temp_file = tempfile.NamedTemporaryFile()
    e = list(islice(f, 4))
    if not e:
        temp_file.close()
        break
    # e.sort(key=lambda line:int(line.split()[1]))
    e.sort(key=lambda line: int(line.split()[1]))
    temp_file.writelines(e)
    temp_files.append(temp_file)
    temp_file.flush()
    temp_file.seek(0)
f.close()

aux = []
z = 0
while len(temp_files) != 1:
    while z < len(temp_files)-1:
        tem = tempfile.NamedTemporaryFile()
        t1 = temp_files[z]
        t2 = temp_files[z+1]
        t1.seek(0)
        t2.seek(0)
        n = 2
        e1 = None
        e2 = None
        while True:
            if not e1:
                e1 = list(islice(t1, 2))
            if not e2:
                e2 = list(islice(t2, 2))
            if not e1 and not e2:
                break
            elif e1 and not e2:
                tem.writelines(imap('{}'.format,e1))
                e1 = None
                continue
            elif not e1 and e2:
                tem.writelines(imap('{}'.format,e2))
                e2 = None
                continue
            i = 0
            j = 0
            while i<len(e1) and j<len(e2):
                l1 = e1[i]
                l2 = e2[j]
                if int(l1.split()[1]) == int(l2.split()[1]):
                    tem.writelines(imap('{}'.format,[l1,l2]))
                    i+=1
                    j+=1
                elif int(l1.split()[1]) < int(l2.split()[1]):
                    tem.writelines(imap('{}'.format,[l1]))
                    i+=1
                else:
                    tem.writelines(imap('{}'.format,[l2]))
                    j+=1
            if i>=len(e1):
                e1 = None
            else:
                e1 = e1[i:]
            if j>= len(e2):
                e2 = None
            else:
                e2 = e2[j:]
        z+=2
        aux.append(tem)
        t1.close()
        t2.close()
        tem.flush()
        tem.seek(0)
    temp_files = aux
    z = 0
    aux = []
with open("o.txt",'w') as out:
    out.writelines(imap('{}'.format,temp_files[0]))
于 2017-05-24T21:00:07.890 回答
-2

尝试使用 Blaze 的核心处理 ( http://blaze.readthedocs.io/en/latest/ooc.html )

于 2017-05-22T13:10:47.940 回答