Python列表:在具有重复值的列表中使用heapq.nlargest的索引

5

假设我有一个数字列表:

my_list = [3, 8, 4, 2, 8, 1, 1, 2, 5, 1]

现在我想找到这个列表中最大的两个数的索引。所以,我尝试:

import heapq
max_vals = heapq.nlargest(2, my_list)
index1 = my_list.index(max_vals[0])
index2 = my_list.index(max_vals[1])
print index1
print index2

在这个例子中,index1index2都等于1。这是因为max_vals的值对于这两个元素都是8my_list.index()函数只会搜索到第一个8
如何获取前两个最大值的索引呢?这样可以使index1仍然等于1,但是index2现在应该等于4,对应列表中的另一个8
顺便说一下,似乎在列表中查找最大值,然后找出该值的索引比较低效。难道没有一种方法可以在一次遍历列表的过程中完成这个任务吗?
谢谢。

3
如果列表中有三个 8,会怎样? - mgilson
@mgilson:然后heapq.nlargest的文档中记录了返回前两个元素,因为它被记录为等效于sorted(iterable, key=key, reverse=True)[:n],而且sorted是一种稳定排序。当内容是小整数时,您可能无法区分差异,因为在CPython中,任何具有值8的两个int都具有相同的标识,但至少暗示了应该返回哪些索引的答案 :-) - Steve Jessop
1
@SteveJessop -- 我明白 heapq 会发生什么 - 我更感兴趣的是 OP 是否考虑过这一点,如果取前两个 8 值是期望的结果,还是 OP 实际上想要所有三个 8 值。 - mgilson
1个回答

10
您可以在enumerate(list)上应用heapq.nlargest
>>> import heapq
>>> data = heapq.nlargest(2, enumerate(my_list), key=lambda x:x[1])
>>> indices, vals = zip(*data)
>>> indices
(1, 4)
>>> vals
(8, 8)

4
可以使用 heapq.nlargest(2, range(len(my_list)), key=my_list.__getitem__) 获取列表元素最大的两个索引。 - Martijn Pieters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接