python - 以相同顺序打印列表的最大值而不创建新列表

标签 python list dictionary

这里有一个列表

[9,1,2,11,8]

我需要打印此列表中的前 3 名,例如

[9,11,8]

很容易排序和获取最高值并循环遍历相同的复制列表以找到给定顺序的最高值 但我不应该为此任务使用新列表。 这可能吗?

最佳答案

def k_largest(iterable, k=3):
    it = iter(iterable)
    result = [next(it) for _ in range(k)] # O(k) space
    r_min = min(result)
    for elem in it:
        if elem > r_min:
            result.remove(r_min)  # O(n*k) time
            result.append(elem)
            r_min = min(result)
    return result

在平局的情况下,第一个值获胜。如果您想要最后一个值取胜,只需将 > 更改为 >=

对于大数据和小选择,这是一个很好的方法,即其中 n >> k 其中 n 是输入的长度,k 是选择的数字。 在这种情况下,k 项无关紧要,因此该方法的时间复杂度为 O(n),有利于 O(n log n) 的基于排序的方法。如果 k 很大,这将不再是一个好的解决方案。您应该考虑维护一个排序的结果集,将其一分为二以进行插入,或许还可以使用 quickselect找到最大值。

使用 Python stdlib 的 heapq.nlargest 可以使用另一个具有更简单代码的选项。 ,尽管在实践中通常会更慢:

import heapq
from operator import itemgetter

def k_largest_heap(iterable, k=3):
    ks = heapq.nlargest(k, enumerate(iterable), key=itemgetter(1))
    return [k for i, k in sorted(ks)]

认为这是O(n log(k)),尽管不可否认我在这里已经达到了知识的边缘。

10,000 个整数列表的一些计时:

from random import randint
nums =  [randint(1, 10000) for _ in range(10000)]
%timeit k_largest(nums)
# 331 µs ± 4.69 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit k_largest_heap(nums)
# 1.79 ms ± 27.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%timeit top_three(nums)
# 1.39 ms ± 16.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

注意 top_three 实现是来自用户 Delirious Lettuce here 的解决方案.

关于python - 以相同顺序打印列表的最大值而不创建新列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50705975/

相关文章:

Python比较两个不同列表中的元素

java - 增强的 for 循环从 List 的一部分开始

python - 如何优雅地迭代列表或字典

python - 通过 SQLAlchemy 插入 MySQL 时截断太长的 varchar

Python从.py文件中提取多行注释

python - 在 python 和嵌套列表中的 for 循环中追加

r - R中列表列表中的元素

python - 查找字符串之间的重复模式

python - 更改字典中的列表会更改所有列表

c# 如何将字典保存到文本文件