我有一个n数字的数组,例如[1,4,6,2,3]
。排序后的数组是[1,2,3,4,6]
,旧数组中的这些数字的索引是0,3,4,1和2.给定一个n数组的数组,可以找到这个索引数组的最佳方法是什么?对列表进行排序,然后按照原始顺序给出元素索引
我的想法是运行每个元素的订单统计。然而,由于我不得不多次重写这个函数(比赛中),我想知道是否有一个简短的方法来做到这一点。
我有一个n数字的数组,例如[1,4,6,2,3]
。排序后的数组是[1,2,3,4,6]
,旧数组中的这些数字的索引是0,3,4,1和2.给定一个n数组的数组,可以找到这个索引数组的最佳方法是什么?对列表进行排序,然后按照原始顺序给出元素索引
我的想法是运行每个元素的订单统计。然而,由于我不得不多次重写这个函数(比赛中),我想知道是否有一个简短的方法来做到这一点。
>>> 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)。
这将创建一个枚举列表,根据原始键对其进行排序,然后返回关联的索引。一个非常有效的解决方案,关于速度和代码长度。 – 2014-08-28 02:17:00
为什么感谢你。我可能应该评论它,谢谢你,列表的理解可能有点难以消化。 – user2085282 2014-08-28 02:19:40
完美!谢谢! – neutralino 2014-08-28 03:11:18
这里是另一种方式:
>>> sorted(xrange(len(a)), key=lambda ix: a[ix])
[0, 3, 4, 1, 2]
这种方法排序不是原来的名单,但其指数(带xrange
创建),使用原来的列表作为排序键。
如果要生成完整的索引列表来排序它,为什么使用'xrange'而不是'range'? – 2014-08-28 02:47:35
@MarkReed:我认为'sorted'会一次消耗'xrange'的一个元素。这意味着只会生成一个列表(排序后的版本);未排序的索引列表将不会预先生成并存储。 – BrenBarn 2014-08-28 02:49:37
如果您正在对数据进行大量统计,则使用numpy数组而不是列表可能会有所帮助。如果你选择这样做,这会工作:
import numpy as np
a = np.array([1,4,6,2,3])
b = np.argsort(a)
argsort()可以在列表上操作为好,但我认为,在这种情况下,简单地将数据拷贝到一个数组第一。
这应该做的伎俩:
from operator import itemgetter
indices = zip(*sorted(enumerate(my_list), key=itemgetter(1)))[0]
你能证明你已尝试过? – whereswalden 2014-08-28 02:07:59