我有一个整数列表(从0到N),我需要创建一个新列表,其中包含第一个列表中每个整数的索引。
即,给定
s = [4, 2, 6, 3, 0, 5, 1]
确定r
,以便s[r[i]] = i
r = [4, 6, 1, 3, 0, 5, 2]
我目前的解决方案是
r = [s.index(i) for i in xrange(len(s))]
有更好的方法吗?
答案 0 :(得分:4)
我假设S
中的每个整数只出现一次。您当前的解决方案可行,问题是s.index
执行O(N)
搜索,使其成为O(N**2)
操作。
对于大型列表,我希望以下代码更快,因为它是O(N)
# initialise the whole list with some value
r = [-1]*N
for j, s_j in enumerate(s):
r[s_j] = j
# if any element of r is still -1 then you know it did not appear in s
答案 1 :(得分:3)
看起来字典对此更好:
s = [4, 2, 6, 3, 0, 5, 1]
r = dict((v,i) for i,v in enumerate(s))
测试:
>>> for i,_ in enumerate(s):
... print i, s[r[i]]
...
0 0
1 1
2 2
3 3
4 4
5 5
6 6
答案 2 :(得分:2)
就个人而言,你展示的方法很棒。
字典可以工作 - 这将是我的第一次尝试:
r = {v:i for i, v in enumerate(s)}
或者,如果您必须使用列表,则另一种方法是:
r = [x[0] for x in sorted(enumerate(s), key=lambda v:v[1])]
答案 3 :(得分:2)
您是否可以使用numpy
?
>>> import numpy as np
>>> s = np.array([4, 2, 6, 3, 0, 5, 1])
>>> s.argsort()
array([4, 6, 1, 3, 0, 5, 2], dtype=int64)
答案 4 :(得分:2)
我用timit模块做了一个简单的基准测试@ 10 ^ 6次迭代 - 重复5次。
DaveP : 1.16 +/- 0.04s
koblas: 7.02s +/- 0.04s
Jon Clements: 1.82 +/- 0.02s
Zero Piraeus: 6.04 +/- 0.4s
最后但并非最不重要:
r=s[:]
[r[s[i]] for i in s]
我的建议:1.11 +/- 0.03s