(不,这不是家庭作业也不是比赛,即使它看起来像是一个。)
我在Python中有一个包含数字A
的列表range(0, len(A))
。这些数字不是有序的,但所有这些数字都存在于列表中。
我正在寻找一种简单的方法来构建一个列表B
,其中索引和值已被交换,即一个列表,对于每个整数n
,包含{{1}的位置在n
。
示例:
A
我可以将代码分别生成A = [0, 4, 1, 3, 2]
B = [0, 2, 4, 3, 1]
或生成B
的代码。特别是,这是我如何生成A
:
A
最好的方法是什么?
答案 0 :(得分:6)
如何分配到预先分配的B:
>>> A = [0, 4, 1, 3, 2]
>>> B = [0] * len(A)
>>> for k, v in enumerate(A): B[v] = k
>>> B
[0, 2, 4, 3, 1]
那将是O(n)。
答案 1 :(得分:3)
使用enumerate()
function用索引装饰每个值,在值上排序sorted()
,然后再次取消装饰以按值顺序提取索引:
[i for i, v in sorted(enumerate(A), key=lambda iv: iv[1])]
这具有O(NlogN)时间复杂度,因为我们使用了排序。
演示:
>>> A = [0, 4, 1, 3, 2]
>>> [i for i, v in sorted(enumerate(A), key=lambda iv: iv[1])]
[0, 2, 4, 3, 1]
我们还可以使用预建列表为O(N)解决方案分配索引:
B = [0] * len(A)
for i, v in enumerate(A):
B[v] = i
演示:
>>> B = [0] * len(A)
>>> for i, v in enumerate(A):
... B[v] = i
...
>>> B
[0, 2, 4, 3, 1]
如果时间复杂性是一个大问题,这可能是更好的选择;对于N = 100,排序方法将花费大约461步,而预建列表方法则为100步。
答案 2 :(得分:0)
A = [0, 4, 1, 3, 2]
B = [None]*len(A)
for i, x in enumerate(A):
B[x] = i
print B
res:[0, 2, 4, 3, 1]
答案 3 :(得分:0)
这很天真;
[ [ x[0] for x in enumerate(A) if x[1] == i][0] for i in range(len(A)) ]
这很完美,
[A.index(A.index(i)) for i in A]
更好;
[A.index(i[0]) for i in enumerate(A)]
这一个击败另一个;
[A.index(i) for i in range(len(A))]
证明;
import random as r
for l in [ r.sample(range(5),5) for n in range(5) ]:
A = l
B = [A.index(A.index(i)) for i in A]
print "A is : ", A
print "B is : ", B
print "Are B's elements indices of A? : ", A == [B.index(B.index(i)) for i in B]
print