我正在使用heapq从列表列表中获取最大的元素。我写的程序如下。
import csv
import heapq
f = open("E:/output.csv","r")
read = csv.reader(f)
allrows = [row for row in read]
for i in xrange(0,2):
print allrows[i]
allrows.sort(key=lambda x: x[2]) #this is working properly
it=heapq.nlargest(20,enumerate(allrows),key=lambda x:x[2]) #error
我只想要前20个元素。因此,我没有考虑使用堆。我得到的错误是,
Traceback (most recent call last):
File "D:\eclipse_progs\DaDv\IMDB\Assignment1.py", line 42, in <module>
it=heapq.nlargest(2,enumerate(allrows),key=lambda x:x[2])
File "C:\Python27\lib\heapq.py", line 470, in nlargest
result = _nlargest(n, it)
File "D:\eclipse_progs\DaDv\IMDB\Assignment1.py", line 42, in <lambda>
it=heapq.nlargest(2,enumerate(allrows),key=lambda x:x[2])
IndexError: tuple index out of range
我能知道为什么会收到错误以及如何解决错误。有没有使用heapq的属性我缺少。
答案 0 :(得分:2)
enumerate()
返回超过2元组的可迭代。因此,在第二个示例中访问x[2]
总是超出范围(唯一有效的索引是0和1)。
要使第二个示例与第一个示例等效,您应该直接传递allrows
而不是使用enumerate()
:
it = heapq.nlargest(20, allrows, key=lambda x:x[2])
如果您需要保留原始索引,enumerate()
是可行的方法。但是,您还需要在键功能中使用额外的间接级别:
it = heapq.nlargest(20, enumerate(allrows), key=lambda x:x[1][2])
^^^^^^^^^ ^^^
答案 1 :(得分:2)
感谢NPE点亮问题,作为替代答案,您可以将所有行与itertools.chain()
连接起来,并通过排序获得前20个元素,其性能高于heapq
:
from itertools import chain
sorted(chain(*allrows))[-20:]
如果您尝试,nlargest()
和nsmallest()
函数最合适
找到相对较少的物品。如果你只是想找到单个最小的
或最大项(N=1)
,使用min()
和max()
会更快。同样,如果N是关于
与集合本身相同的大小,通常更快地对其进行排序并采取切片(即,
使用sorted(items)[:N]
或sorted(items)[-N:]
)。