从巨大的文本文件中列出前5个大数字的最佳方法

时间:2018-09-03 10:28:53

标签: python

试图找到最好和简单的方法来列出150G文本文件中的前5个数字。

我正在搜索的文件在每一行中只有数字,如下所示。

456789876
098765
36
48987
4509876
.
.
.

尝试了以下程序,但仍然只显示数字中的第一个数字,而不显示完整的数字。

from heapq import nlargest

data=open('number.txt','r')
text=data.read()
print (text)
print nlargest(5, (text))
data.close()

还有其他选择前5名的方法吗?

2 个答案:

答案 0 :(得分:3)

您没有将数据视为数字。相反,您是将整个文件内容(一个很大的字符串)传递给nlargest(),除了给您以字典顺序的最后一个字符之外,它什么也不能做。在这种情况下,字符'9'在字符'8'之后排序。

您需要a)逐行读取输入内容,而不是一个大字符串,b)将数据转换为整数,以便将它们与数字值进行比较:

from heapq import nlargest

def as_numbers(it):
    for line in it:
        try:
            yield int(line)
        except ValueError:
            # not a line with a number, skip
            continue

with open('number.txt') as data:
    five_largest = nlargest(5, as_numbers(data))                
    print(five_largest)

我在这里使用了生成器函数将行转换为整数,因为这样可以更轻松地继续使用heapq.nlargest()(这绝对是用于此工作的正确工具,因为它可以有效地保持在O(NlogK)时间中可用的前n个值,因此对于固定的K = 5个项目,该项目基本上是线性的,并且仅与文件中整数值的数量成比例)。生成器函数负责转换为int(),跳过所有无法转换的行。

还要注意在打开的文件对象中使用with;在with块的末尾,文件将自动为您关闭,无需在此处显式调用data.close()。即使也有例外,也会这样!

演示:

>>> from heapq import nlargest
>>> from io import StringIO
>>> random_data = '\n'.join([str(random.randrange(10**6)) for _ in range(10000)])  # 10k lines of random numbers between 0 and 1 million
>>> random_data.splitlines(True)[1042:1045] # a few sample lines
['39909\n', '15068\n', '420171\n']
>>> sample_file = StringIO(random_data)  # make it a file object
>>> def as_numbers(it):
...     for line in it:
...         try:
...             yield int(line)
...         except ValueError:
...             # not a line with a number, skip
...             continue
...
>>> nlargest(5, as_numbers(sample_file))
[999873, 999713, 999638, 999595, 999566]

答案 1 :(得分:-1)

输入:

456789876
098765
36
48987
4509876
563456
47345734
6234
67456
235423
7348
3
656    

代码:

data=open('number.txt','r')
text=data.readlines()#read the file line to line and introduce in a list of string
numbers = map(int, text)#convert the list of string in list of int
numbers.sort()#sort your list
print (numbers[-5:])#print the 5 largest
print (numbers[:5])#print the 5 smaller

结果:

[235423, 563456, 4509876, 47345734, 456789876]
[3, 36, 656, 6234, 7348]