如果你需要排序后的列表和索引列表,你可以这样做:
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]
或者对于 Python <2.4(没有 itemgetter
或 sorted
):
temp = [(v,i) for i,v in enumerate(L)]
temp.sort
indices, L_sorted = zip(*temp)
p.s. zip(*iterable)
的惯用语反转了zip过程(即解压缩)。
更新:
针对您的特定要求:
"我有一个特殊需求,需要基于对象的属性对对象列表进行排序。然后,我需要重新排序相应的列表以匹配新排序列表的顺序。"
那是一种冗长的方式。您可以通过将两个列表一起压缩,然后使用对象属性作为排序关键字进行排序(并在排序后解压缩),以单个排序实现该目的。
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))
这是一个简单的示例,使用字符串来表示您的对象。 在这里,我们使用字符串的长度作为排序的关键字:
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]
[obj1, obj2, ...]
->[(0,obj1), (1, obj2), ...]
,并对此列表进行排序。然后您可以立即获得原始索引的新顺序。 - Felix Klingorder
向量和rank
向量之间的区别,例如[2,0,1,3,4]是order
向量,而对应的rank
向量则为[1,2,0,3,4]。详见https://dev59.com/WsKVzogBFxS5KdRj5vjM。 - djvg