0

我有一个文件,其中包含我正在循环的值。该文件由具有 x 和 y 值的两列组成。我将 x 和 y 值添加到列表中,例如

example_list = []
for line in f:
    example_list.append([line.split()[0], line.split()[1]])

但是,我希望列表最长为 15 个列表,仅保留line.split()[1]. 两种方法是

example_list = []
for line in f:
    example_list.append([line.split()[0], line.split()[1]])
top_15 = example_list.sort(key=operator.itemgetter(1), reverse=True)[:15]

或者

example_list = []
count = 0
for line in f:
    if count < 15:
        example_list.append([line.split()[0], line.split()[1]])
        count += 1
    else:
        example_list.sort(key=operator.itemgetter(1))
        if example_list[0][1] < line.split()[1]:
            example_list[0] = line.split()[1]

但是,我不想读取内存中的整个文件或调用sort每一行。有什么更好的方法来保持列表列表的排序,以便只添加一个新元素来替换列表中的最低元素?

4

1 回答 1

3

您正在寻找heapq模块;堆可让您在进行过程中有效地保留前 N 个项目。甚至还有针对您的确切用例的专用功能:

from heapq import nlargest
from operator import itemgetter

largest_15 = nlargest(15, (line.split()[:2] for line in f), itemgetter(1))

这会传入一个生成器表达式,从而有效地处理循环。

在引擎盖下,这个方法:

  • 获取前 15 个元素并从中创建一个堆。
  • 为以下所有项目调用heappushpop()堆;这会将项目添加到堆中,然后删除最小的项目。因此,堆只包含 15 个最大的项目。
  • 当迭代完成时,堆列表被排序。
于 2013-10-01T08:53:23.560 回答