整数 (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 から 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))]
より良い方法はありますか?
の各整数が 1 回だけ出現すると仮定し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
これには辞書の方が適しているようです:
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
使用しても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)
私は 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
個人的には、あなたが示したアプローチは素晴らしいです。
どちらの辞書でも機能します-それが私の最初の試みです:
r = {v:i for i, v in enumerate(s)}
または、リストを使用する必要がある場合、別のアプローチは次のとおりです。
r = [x[0] for x in sorted(enumerate(s), key=lambda v:v[1])]