2014-08-28 18 views
5

我有一个n数字的数组,例如[1,4,6,2,3]。排序后的数组是[1,2,3,4,6],旧数组中的这些数字的索引是0,3,4,1和2.给定一个n数组的数组,可以找到这个索引数组的最佳方法是什么?对列表进行排序,然后按照原始顺序给出元素索引

我的想法是运行每个元素的订单统计。然而,由于我不得不多次重写这个函数(比赛中),我想知道是否有一个简短的方法来做到这一点。

+1

你能证明你已尝试过? – whereswalden 2014-08-28 02:07:59

回答

11
>>> a = [1,4,6,2,3] 
>>> [b[0] for b in sorted(enumerate(a),key=lambda i:i[1])] 
[0, 3, 4, 1, 2] 

说明:

enumerate(a)返回了由原始列表索引和值的元组的枚举:[(0, 1), (1, 4), (2, 6), (3, 2), (4, 3)]

然后sorted基于原始数值lambda i:i[1]key排序(项目每个元组1个)。

最后,列表理解[b[0] for b in ... ]返回原始索引(每个元组的项目0)。

+0

这将创建一个枚举列表,根据原始键对其进行排序,然后返回关联的索引。一个非常有效的解决方案,关于速度和代码长度。 – 2014-08-28 02:17:00

+0

为什么感谢你。我可能应该评论它,谢谢你,列表的理解可能有点难以消化。 – user2085282 2014-08-28 02:19:40

+0

完美!谢谢! – neutralino 2014-08-28 03:11:18

1

这里是另一种方式:

>>> sorted(xrange(len(a)), key=lambda ix: a[ix]) 
[0, 3, 4, 1, 2] 

这种方法排序不是原来的名单,但其指数(带xrange创建),使用原来的列表作为排序键。

+0

如果要生成完整的索引列表来排序它,为什么使用'xrange'而不是'range'? – 2014-08-28 02:47:35

+0

@MarkReed:我认为'sorted'会一次消耗'xrange'的一个元素。这意味着只会生成一个列表(排序后的版本);未排序的索引列表将不会预先生成并存储。 – BrenBarn 2014-08-28 02:49:37

1

如果您正在对数据进行大量统计,则使用numpy数组而不是列表可能会有所帮助。如果你选择这样做,这会工作:

import numpy as np 
a = np.array([1,4,6,2,3]) 
b = np.argsort(a) 

argsort()可以在列表上操作为好,但我认为,在这种情况下,简单地将数据拷贝到一个数组第一。

0

这应该做的伎俩:

from operator import itemgetter 
indices = zip(*sorted(enumerate(my_list), key=itemgetter(1)))[0] 
相关问题