我正在考虑以前没有遇到的问题,我正在尝试确定最有效的算法。
我正在迭代两个列表,使用每对元素来计算我想要排序的值。我的最终目标是获得前20名的成绩。我可以将结果存储在第三个列表中,按绝对值对列表进行排序,然后简单地将前二十个切片,但这并不理想。
由于这些列表有可能变得非常大,我理想情况下只想存储前20个绝对值,在计算新的最高值时逐出旧值。
在python中实现它的最有效方法是什么?
答案 0 :(得分:11)
heapq.nlargest(n, iterable[, key])
使用 iterable 定义的数据集中的 n 最大元素返回一个列表。 key ,如果提供,则指定一个参数的函数,该函数用于从iterable中的每个元素中提取比较键:
key=str.lower
相当于:sorted(iterable, key=key, reverse=True)[:n]
答案 1 :(得分:4)
您可以使用izip
并行迭代这两个列表,并构建一个生成器来懒散地对它们进行计算,然后heapq.nlargest
有效地保持顶部n
:
from itertools import izip
import heapq
list_a = [1, 2, 3]
list_b = [3, 4, 7]
vals = (abs(a - b) for a, b in izip(list_a, list_b))
print heapq.nlargest(2, vals)
答案 2 :(得分:1)
有一个大小为20的tupples列表初始化,小于计算的最小结果,两个索引为-1。在计算结果时,将结果附加到结果列表中,使用所产生的对的索引,仅对值进行排序并将列表修剪为长度20.应该合理有效,因为您只需对长度为21的列表进行排序。
答案 3 :(得分:1)
我知道已经选择了最佳答案,但出于教育目的,你也可以考虑我的答案。
我希望没有拼写错误:
def some_name(list_a, list_b):
if len(list_a) != len(list_b):
raise Exception("Too bad")
result_list = []
for result in (list_a[i] + list_b[i] for i in range(len(list_a))):
if len(result_list) >= 20:
if result_list[0] > result:
continue
result_list = result_list[1:]
result_list.append(result)
result_list.sort()
经过一些重构 - 它几乎完成了heapq.nlargest
会做的事情(当然我们必须保持结果自己排序):
def some_name(list_a, list_b):
if len(list_a) != len(list_b):
raise Exception("Too bad")
result_list = []
for result in (list_a[i] + list_b[i] for i in range(len(list_a))):
result_list.append(result)
result_list.sort()
result_list = result_list[-20:]