【发布时间】:2011-03-09 13:35:40
【问题描述】:
如何返回可迭代的第 n 个最大项的原始列表中的索引
heapq.nlargest(2, [100, 2, 400, 500, 400])
output = [(3,500), (2, 400)]
这已经花费了我几个小时。我想不通。
【问题讨论】:
如何返回可迭代的第 n 个最大项的原始列表中的索引
heapq.nlargest(2, [100, 2, 400, 500, 400])
output = [(3,500), (2, 400)]
这已经花费了我几个小时。我想不通。
【问题讨论】:
>>> seq = [100, 2, 400, 500, 400]
>>> heapq.nlargest(2, enumerate(seq), key=lambda x: x[1])
[(3, 500), (2, 400)]
【讨论】:
您可以将list.index 与map 结合使用,这对于小型n 来说很快(注意list.index 返回值为第一个 项的列表中的索引,其值为x):
>>> iterable = [100, 2, 400, 500, 400]
>>> map(iterable.index, heapq.nlargest(2, iterable))
[3, 2]
查看相关值...
>>> map(lambda n: (n, iterable.index(n)), heapq.nlargest(2, iterable))
[(500, 3), (400, 2)]
对于更大的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
【讨论】:
iterable.index 似乎快了近一倍(请参阅我的编辑)。
index 文档,但您可能没有注意到那里非常重要的一点:“返回 first 项列表中的索引 [...]”
n = 2 你看到你看到的东西时,你的“解决方案”如何与n = 10 一起执行?
n = 10 产生相同的性能结果。对于长度为 10000 和 n = 100 的数组,你赢了,恭喜 ;)