【问题标题】:Python: quickest way to sort list and keep indexesPython:排序列表和保留索引的最快方法
【发布时间】:2021-06-15 03:23:30
【问题描述】:

我正在尝试找到对列表进行排序的最快方法。 例如,假设我试图对以下列表进行排序

lst = [1, 0, -1, 0.1, 0, 5, 10, 4]

我最后想要的是获得排序列表,但也能够在排序之前知道他们在lst 中的索引是什么。

我目前使用的方法是这样的

lst = [1, 0, -1, 0.1, 0, 5, 10, 4]
lst = list(enumerate(lst))
lst.sort(key = lambda x: x[1], reverse = True)

这样做会给lst = [(6, 10), (5, 5), (7, 4), (0, 1), (3, 0.1), (1, 0), (4, 0), (2, -1)]

现在我不一定需要有元组 (idx, value),它可以是两个单独的列表。重要的部分是对值进行排序,并且还知道列表lst 中的“原始”索引是什么。例如得到:

lst_val = [10, 5, 4, 1, 0.1, 0, 0, -1]
lst_idx = [6, 5, 7, 0, 3, 1, 4, 2]

现在我想知道是否有更快/更有效的方法来排序,因为我可以有一个包含超过 200,000 个值的列表。

允许使用numpy,但除此之外我认为不允许使用其他模块。

【问题讨论】:

  • 这能回答你的问题吗? Transpose/Unzip Function (inverse of zip)?
  • @quamrana 不是真的,我正在尝试对列表进行排序,并跟踪索引,而不是尝试从列表中分离索引...
  • 答案指出zip是它自己的逆。您创建了一个list,就好像您将值和它们的索引压缩在一起一样。现在您需要将它们解压缩到两个列表中。

标签: python arrays performance numpy sorting


【解决方案1】:

你不使用lst_val = sorted(lst) 然后使用.index() 来查找值的索引。像这样的:

lst = [1, 0, -1, 0.1, 0, 5, 10, 4]
lst_val = sorted(lst)
lst_idx = []

for i in lst_val:
    lst_idx.append(lst.index(i))

【讨论】:

  • 不不,.indexO(n),所以这是 O(n^2)
  • 我猜你可以在一行中做for循环
  • 一行循环是什么意思?它如何改变循环的复杂性?
  • 稍微修改一下并使用list()
  • 问题是我几乎知道如何排序,但我正在尝试找到最快的方法。我需要对值以及索引进行排序。我正在尝试弄清楚如何做到这一点,以便程序可以更快地执行自身......
【解决方案2】:

如果您需要显着加速,您必须使用numpy

import numpy as np

np_lst = np.array(lst)

sorted_indices = np_lst.argsort() #array([2, 1, 4, 3, 0, 7, 5, 6])

然后,您可以通过这种方式对数组进行“排序”:

np_lst[sorted_indices]
#array([-1. ,  0. ,  0. ,  0.1,  1. ,  4. ,  5. , 10. ])

您也可以通过以下方式获得它:

np_lst[sorted_indices[::-1]] 
#array([10. ,  5. ,  4. ,  1. ,  0.1,  0. ,  0. , -1. ])

【讨论】:

  • 假设我有一个包含 200,000 个值的列表,如果我必须通过执行 lst = np.array(lst) 将列表转换为 numpy array,使用您的方法会更快吗?然后用np.sort排序?
  • @needle 我很确定加速很显着
  • 如果我将 lst 创建为 numpy array,然后将值更新到 numpy 数组,您认为会更快吗?
  • @needle--from Fastest way to grow a numpy numeric array 增长 Python 列表然后在排序之前转换为 numpy 数组而不是增长 numpy 数组会更快。
  • @needle 迭代地使用numpy.append 总是一个坏主意。尝试这样的事情:numpy.org/devdocs/reference/generated/numpy.loadtxt.html
猜你喜欢
  • 2015-06-26
  • 2010-10-08
  • 1970-01-01
  • 2018-05-02
  • 2019-10-31
  • 2011-08-25
  • 2012-11-16
  • 2010-10-31
  • 2021-11-10
相关资源
最近更新 更多