how to return index of a sorted list?
我需要对列表进行排序,然后返回带有列表中已排序项目的索引的列表。 例如,如果要排序的列表是
这个问题以字节为单位发布,但我想我会在这里重新发布。
http://bytes.com/topic/python/answers/44513-sorting-list-then-return-index-sorted-item
我的具体需求是根据对象的属性对对象列表进行排序。 然后,我需要重新排序对应的列表以匹配新排序的列表的顺序。
有什么好方法吗?
您可以使用python排序函数的
1 2 3 4 | >>> s = [2, 3, 1, 4, 5] >>> sorted(range(len(s)), key=lambda k: s[k]) [2, 0, 1, 3, 4] >>> |
如果您有可用的numpy,可以使用numpy的argsort方法执行此操作:
1 2 3 4 5 6 7 | >>> 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]) |
如果不可行,从这个问题中得出,这是最快的方法:
1 2 3 | >>> vals = [2,3,1,4,5] >>> sorted(range(len(vals)), key=vals.__getitem__) [2, 0, 1, 3, 4] |
如果同时需要排序列表和索引列表,则可以执行以下操作:
1 2 3 4 5 6 7 | 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(无
1 2 3 | temp = [(v,i) for i,v in enumerate(L)] temp.sort indices, L_sorted = zip(*temp) |
ps。
更新:
要满足您的特定要求:
"my specific need to sort a list of objects based on a property of the objects. i then need to re-order a corresponding list to match the order of the newly sorted list."
这是一个漫长的做法。您可以通过将两个列表都压缩在一起,然后使用object属性作为您的排序键进行排序(然后再解压缩),从而实现一次排序。
1 2 3 | 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)) |
这是一个简单的示例,使用字符串表示您的对象。在这里,我们使用字符串的长度作为排序的键:
1 2 3 4 5 6 7 8 | 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] |
怎么样
1 2 | l1 = [2,3,1,4,5] l2 = [l1.index(x) for x in sorted(l1)] |
您可以使用
或者您可以执行以下操作:
1 2 | test = [2,3,1,4,5] idxs = list(zip(*sorted([(val, i) for i, val in enumerate(test)])))[1] |
我会做的,看看您的特定需求:
假设您的列表
1 2 | keys = {i:j.x for i,j in zip(a, b)} a.sort(key=keys.__get_item__) |
使用此方法,您可以将列表排序,而不必构造您要的中间排列列表。
直接出自
1 2 3 | >>> # dictionary sorted by value >>> OrderedDict(sorted(d.items(), key=lambda t: t[1])) OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)]) |
适应原始帖子中的示例:
1 2 3 | >>> l=[2,3,1,4,5] >>> OrderedDict(sorted(enumerate(l), key=lambda x: x[1])).keys() [2, 0, 1, 3, 4] |
有关详细信息,请参见http://docs.python.org/library/collections.html#collections.OrderedDict。