如何返回一个sorting列表的索引?
我需要对列表进行sorting,然后返回列表中带有sorting项目索引的列表。 例如,如果我想sorting的列表是[2,3,1,4,5]
,我需要返回[2,0,1,3,4]
。
这个问题是张贴在字节上,但我想我会在这里重新发布。 http://bytes.com/topic/python/answers/44513-sorting-list-then-return-index-sorted-item
我的具体需要根据对象的属性对对象列表进行sorting。 然后我需要重新排列相应的列表来匹配新sorting列表的顺序。
有没有一个好的方法来做到这一点?
您可以使用pythonsorting函数的key
参数来对索引数组进行sorting。
>>> s = [2, 3, 1, 4, 5] >>> sorted(range(len(s)), key=lambda k: s[k]) [2, 0, 1, 3, 4] >>>
你可以用numpy的argsort方法做到这一点,如果你有numpy:
>>> 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])
如果没有,从这个问题来看,这是最快的方法:
>>> vals = [2,3,1,4,5] >>> sorted(range(len(vals)), key=vals.__getitem__) [2, 0, 1, 3, 4]
怎么样
l1 = [2,3,1,4,5] l2 = [l1.index(x) for x in sorted(l1)]
如果你需要sorting列表和指数列表,你可以这样做:
>>> 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)
ps zip(*iterable)
成语反转压缩过程(unzip)。
更新:
为了处理你的具体要求:
“我特别需要根据对象的属性对对象列表进行sorting,然后我需要重新排列相应的列表以匹配新sorting的列表的顺序。
这是一个冗长的做法。 您可以通过将两个列表压缩在一起,然后使用对象属性作为sorting键(以及之后的解压缩)进行sorting来实现这一目的。
zipped = 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))
这是一个简单的例子,用string来表示你的对象。 这里我们使用string的长度作为分类的关键。
>>> 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]
你可以使用numpy.argsort
或者你可以这样做:
test = [2,3,1,4,5] idxs = zip(*sorted([(val, i) for i, val in enumerate(test)]))[1]
我会做什么,看你的具体需求:
假设列表a
有一些值,而您的键在列表b
存储的对象的属性x
中
keys = {i:jx for i,j in zip(a, b)} a.sort(key=keys.__get_item__)
使用这种方法,您可以定制您的列表,而无需构build您所要求的中间置换列表。
直接从collections.OrderedDict
的文档:
>>> # dictionary sorted by value >>> OrderedDict(sorted(d.items(), key=lambda t: t[1])) OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])
根据原文中的示例进行调整:
>>> 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 。