使用Python列表中的值交换索引?

时间:2015-02-09 12:47:53

标签: python list python-3.x swap indices

(不,这不是家庭作业也不是比赛,即使它看起来像是一个。)

我在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

最好的方法是什么?

4 个答案:

答案 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