在Python中,按原始顺序查找列表中前k个最大的元素

7

假设我有以下列表:

my_list = [3.5, 1.6, 2.4, 8.9, 5.6]

我希望找到原位的前三个最大数字,因此结果应该是:
[3.5, 8.9, 5.6]

我应该怎么做呢?我想我可以找到前三个最大的数字并使用过滤器,但我认为比较浮点数可能不是一个好主意。有什么建议吗?

5个回答

8
使用一个
>>> import heapq
>>> heapq.nlargest(3, my_list)
[8.9, 5.6, 3.5]

在原有的顺序中稍作调整,给这个想法添点光彩:
>>> from operator import itemgetter
>>> i_val = heapq.nlargest(3, enumerate(my_list), key=itemgetter(1))
>>> [val for (i, val) in sorted(i_val)]
[3.5, 8.9, 5.6]

3
小小的问题:这里并没有明确地使用堆。 heapq 模块提供了许多实用函数,这些函数可能或可能不是使用堆实现的; nlargest 的当前实现通常在内部使用堆,但并不总是这样(事实上,如果大多数结果将被保留,则通常不应该使用堆,因为 sorted 通常更有效率)。无论如何,我投了赞成票。这就是 nlargest 的存在目的,并且这是装饰和取消装饰的最干净的示例之一。 - ShadowRanger
1
就 OP 的情况而言,FWIW 它确实进行了堆化。 - wim

3

您可以通过对值进行排序(由enumerate生成的索引-值对),获取最后三个对,然后按索引进行排序(然后从索引-值对中仅获取值,所有这些都在一个列表推导式中完成):

from operator import itemgetter

my_list = [3.5, 1.6, 2.4, 5.6, 8.9]

result = [p[1] for p in sorted(sorted(enumerate(my_list), key = itemgetter(1))[-3:], key = itemgetter(0))]

print(result)

输出:

[3.5, 5.6, 8.9]

3

这个怎么样?

[m for m in my_list if m in sorted(my_list)[-3:]]

您正在从前3个项目中构建一个新列表,列表推导式可以保持项目的顺序。

您的示例顺序使您可以只对其进行排序并取出前3个项目,但我认为您的意思是您可能有前3个项目不按顺序,例如:

my_list = [3.5, 1.2, 0.3, 7.8, 3.3]

这导致了

[3.5,7.8,3.3]

1
这里有一个函数,你可以试一下:

my_list = [3.5, 1.6, 2.4, 5.6, 8.9]
def select_top(a,array):
    new_list = []
    extra_list = []
    for i in range(len(my_list)):
        extra_list.append(my_list[i])
    final_list = []
    for i in range(a):
        new_list.append(extra_list.index(max(extra_list)))
        extra_list.pop(extra_list.index(max(extra_list)))
    new_list = sorted(new_list,reverse=False)
    for i in new_list:
        final_list.append(array[i])
    return final_list
print(select_top(3,my_list))

我认为这远非最佳方案,但您可以进行调整以获取前k个数字,并按其原始顺序返回它们。输出:
[3.5, 5.6, 8.9]

我认为结果是正确的,但我更希望编写更短的代码。还是非常感谢!!! - Chujun Song
当然,这里有一个定义好的函数,无论您选择哪个k或数组的长度,它都可以让您永远不必再编写代码!如果这个答案对您有帮助,请确保点赞并接受最适合您的答案! - Celius Stingher

1
这是我的答案,针对这个问题它有效。
my_list = [3.5, 1.6, 2.4, 8.9, 5.6]
top_k = sorted(my_list)[-3:]
result = list(filter(lambda x : x in top_k,my_list))
print(result)

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