python3利用归并算法对超过内存限制的超大文件进行排序

上一篇文章《python3实现归并排序算法图文详解》中,我们了解了归并排序算法的基本使用逻辑。这一篇文章我们对这个逻辑进行一个延伸,从内存延伸到对硬盘上的文件进行排序,也就是所谓的外部排序。

操作场景

所谓的大文件就是无法一次性全部读到内存中的文件。

为了操作不真的把我机器的内存都榨干,这里假设机器的内存是300MB,刨除一些系统占用,规定每次读到内存的文件大小不能超过200MB

我又用下面的程序创建了一个1GB大小的文件

with open('bigfile.txt','a') as f:
    for i in range(100000000):
        f.write(str(random.randint(100000000,999999999))+'\r\n')

这个文件一共有1亿行,每一行以字符串格式存储着一位9位数,并在末尾加上了换行符,所以每行占据10B,算下来一共有10亿B也就是1GB。

下面要实现的就是在内存占用每次不超过200MB的情况下将这个1GB的文件进行排序。硬盘空间很大,随意使用。

思路分析

大家应该还记得《python3实现归并排序算法图文详解》中的两张图

1-cursor.png

针对一个长列表,我们先分割为两个小列表,并将小列表排好序。利用两个游标从左到右移动,我们对两个已经各自排好序的列表合并成了一个新的有序列表。

2-finish.png

这里的小技巧就是利用了递归的思路,对每一个小的列表都进行了归并排序。

但是我们这个问题不需要这么麻烦。首先将1GB的大文件分解为5个200MB的小文件,这里的小文件就是可以直接读进内存一次性排序。

然后直接对这5个小文件读进内存进行排序

最后再利用归并的思路,通过5个游标分别在5个文件中逐行从左往右移动,将每次最小的一行读到新文件中,达到排序的效果,如下图

3-files.png

代码实现

文件分割

首先来对文件进行分割,每次从原文件读200MB的整行数,然后保存到一个新文件。

这里要补充下python中读取文件的几个方法。f.readlines(n)可以接一个参数n,注意这里的n并不是行数,而是以字节为单位的大小,表示当读到某行时总大小超过了n就不再读下一行。同理,f.readline(n)也可以传递n,表示读取下一行的前n个字节,如果下一行总大小少过n就读取整行。而在某些没有换行符的文件中就不能用这两种读取的方法了

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值