如何返回排序列表的索引?

ale*_*lex 113 python

我需要对列表进行排序,然后返回一个列表,其中包含列表中已排序项的索引.例如,如果我要排序的列表是[2,3,1,4,5],我需要[2,0,1,3,4]返回.

这个问题是在字节上发布的,但我想我会在这里重新发布. http://bytes.com/topic/python/answers/44513-sorting-list-then-return-index-sorted-item

我特别需要根据对象的属性对对象列表进行排序.然后,我需要重新排序相应的列表以匹配新排序列表的顺序.

有没有办法做到这一点?

syk*_*ora 200

您可以使用python排序函数的key参数来对索引数组进行排序.

>>> s = [2, 3, 1, 4, 5]
>>> sorted(range(len(s)), key=lambda k: s[k])
[2, 0, 1, 3, 4]
>>> 
Run Code Online (Sandbox Code Playgroud)


jte*_*ace 67

如果你有numpy可用,你可以使用numpy的argsort方法:

>>> import numpy
>>> vals = numpy.array([2,3,1,4,5])
>>> vals
array([2, 3, 1, 4, 5])
>>> sort_index = numpy.argsort(vals)
>>> sort_index
array([2, 0, 1, 3, 4])
Run Code Online (Sandbox Code Playgroud)

如果没有,请从这个问题中获取,这是最快的方法:

>>> vals = [2,3,1,4,5]
>>> sorted(range(len(vals)), key=vals.__getitem__)
[2, 0, 1, 3, 4]
Run Code Online (Sandbox Code Playgroud)

  • 对于大型阵列,是的。 (3认同)

Sha*_*hin 12

如果您需要排序列表和索引列表,您可以:

L = [2,3,1,4,5]
from operator import itemgetter
indices, L_sorted = zip(*sorted(enumerate(L), key=itemgetter(1)))
list(L_sorted)
>>> [1, 2, 3, 4, 5]
list(indices)
>>> [2, 0, 1, 3, 4]
Run Code Online (Sandbox Code Playgroud)

或者,对于Python <2.4(否itemgettersorted):

temp = [(v,i) for i,v in enumerate(L)]
temp.sort
indices, L_sorted = zip(*temp)
Run Code Online (Sandbox Code Playgroud)

ps这个zip(*iterable)成语颠倒了拉链过程(解压缩).


更新:

处理您的具体要求:

"我特别需要根据对象的属性对对象列表进行排序.然后我需要重新排序相应的列表以匹配新排序列表的顺序."

这是一个冗长的方式.您可以通过将两个列表压缩在一起来实现单一排序,然后使用object属性作为排序键进行排序(并在解压后).

combined = zip(obj_list, secondary_list)
zipped_sorted = sorted(combined, key=lambda x: x[0].some_obj_attribute)
obj_list, secondary_list = map(list, zip(*zipped_sorted))
Run Code Online (Sandbox Code Playgroud)

这是一个简单的例子,使用字符串来表示你的对象.这里我们使用字符串的长度作为排序的关键字:

str_list = ["banana", "apple", "nom", "Eeeeeeeeeeek"]
sec_list = [0.123423, 9.231, 23, 10.11001]
temp = sorted(zip(str_list, sec_list), key=lambda x: len(x[0]))
str_list, sec_list = map(list, zip(*temp))
str_list
>>> ['nom', 'apple', 'banana', 'Eeeeeeeeeeek']
sec_list
>>> [23, 9.231, 0.123423, 10.11001]
Run Code Online (Sandbox Code Playgroud)


siz*_*erz 7

怎么样

l1 = [2,3,1,4,5]
l2 = [l1.index(x) for x in sorted(l1)]
Run Code Online (Sandbox Code Playgroud)

  • 这是'O(n ^ 2)`...... (13认同)
  • 这对重复项不起作用吗? (2认同)