heapq.nlargest原始序列中返回结果的索引

Joe*_*oey 5 python sorting heap

如何在可迭代的第n个最大项的原始列表中返回索引

heapq.nlargest(2, [100, 2, 400, 500, 400])

output = [(3,500), (2, 400)]
Run Code Online (Sandbox Code Playgroud)

这已经花了我几个小时.我无法弄清楚.

Sil*_*ost 21

>>> seq = [100, 2, 400, 500, 400]
>>> heapq.nlargest(2, enumerate(seq), key=lambda x: x[1])
[(3, 500), (2, 400)]
Run Code Online (Sandbox Code Playgroud)


mik*_*iku 5

您可以list.index与 结合使用map,这对于小的来说很快n(注意list.index返回值为 x的第一个项目的列表中的索引):

>>> iterable = [100, 2, 400, 500, 400]
>>> map(iterable.index, heapq.nlargest(2, iterable))
[3, 2]
Run Code Online (Sandbox Code Playgroud)

要查看相关值...

>>> map(lambda n: (n, iterable.index(n)), heapq.nlargest(2, iterable))
[(500, 3), (400, 2)]
Run Code Online (Sandbox Code Playgroud)

更大的n请参见@SilentGhost 的帖子。


编辑:对一些解决方案进行基准测试:

#!/usr/bin/env python
import heapq
from timeit import Timer

seq = [100, 2, 400, 500, 400]

def a(seq):
    """returns [(3, 500), (2, 400)]"""
    return heapq.nlargest(2, enumerate(seq), key=lambda x: x[1])

def b(seq):
    """returns [3, 2]"""
    return map(seq.index, heapq.nlargest(2, seq))

def c(seq):
    """returns [(500, 3), (400, 2)]"""
    map(lambda n: (n, seq.index(n)), heapq.nlargest(2, seq))

if __name__ == '__main__':
    _a = Timer("a(seq)", "from __main__ import a, seq")
    _b = Timer("b(seq)", "from __main__ import b, seq")
    _c = Timer("c(seq)", "from __main__ import c, seq") 

    loops = 1000000

    print _a.timeit(number=loops)
    print _b.timeit(number=loops)
    print _c.timeit(number=loops)

    # Core i5, 2.4GHz, Python 2.6, Darwin
    # 8.92712688446
    # 5.64332985878
    # 6.50824809074
Run Code Online (Sandbox Code Playgroud)