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

用Python列表中的值交换索引?,python,list,python-3.x,swap,indices,Python,List,Python 3.x,Swap,Indices,(不,这既不是家庭作业,也不是竞赛,尽管它看起来像一场竞赛。) 我在Python中有一个列表a,其中包含数字范围(0,len(a))。这些数字不按顺序排列,但都存在于列表中 我正在寻找一种简单的方法来构建一个列表B,其中索引和值已交换,即,对于每个整数n,包含n在a中的位置的列表 例如: A = [0, 4, 1, 3, 2] B = [0, 2, 4, 3, 1] 我可以将生成B的代码单独放置或放置在生成A的代码中。特别是,以下是我如何生成A: A = [value(i) for i in

(不,这既不是家庭作业,也不是竞赛,尽管它看起来像一场竞赛。)

我在Python中有一个列表
a
,其中包含数字
范围(0,len(a))
。这些数字不按顺序排列,但都存在于列表中

我正在寻找一种简单的方法来构建一个列表
B
,其中索引和值已交换,即,对于每个整数
n
,包含
n
a
中的位置的列表

例如:

A = [0, 4, 1, 3, 2]
B = [0, 2, 4, 3, 1]
我可以将生成
B
的代码单独放置或放置在生成
A
的代码中。特别是,以下是我如何生成
A

A = [value(i) for i in range(length)]
执行此操作的最佳方法是什么?

使用以索引修饰每个值,按值排序,然后再次取消修饰以按值顺序提取索引:

[i for i, v in sorted(enumerate(A), key=lambda iv: iv[1])]
这有一个O(NlogN)时间复杂度,因为我们使用了排序

演示:

我们还可以使用预构建的列表为O(N)解决方案分配索引:

B = [0] * len(A)
for i, v in enumerate(A):
    B[v] = i
演示:

如果时间复杂性是一个大问题,这可能是更好的选择;对于N=100,排序方法将需要大约461个步骤,而预构建列表方法需要大约100个步骤。

使用来用索引修饰每个值,对值进行排序,然后再次取消修饰以按值顺序提取索引:

[i for i, v in sorted(enumerate(A), key=lambda iv: iv[1])]
这有一个O(NlogN)时间复杂度,因为我们使用了排序

演示:

我们还可以使用预构建的列表为O(N)解决方案分配索引:

B = [0] * len(A)
for i, v in enumerate(A):
    B[v] = i
演示:


如果时间复杂性是一个大问题,这可能是更好的选择;对于N=100,排序方法需要大约461个步骤,而预构建列表方法需要大约100个步骤。

如何分配给预分配的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)。

分配给预分配的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)

res:
[0,2,4,3,1]

res:
[0,2,4,3,1]

这很幼稚

[[x[0]表示枚举(A)中的x,如果x[1]==i][0]表示范围(len(A))中的i]

这个很好用

[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
这很幼稚,

[[x[0]表示枚举(A)中的x,如果x[1]==i][0]表示范围(len(A))中的i]

这个很好用

[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

这是非常低效的。这是一个O(N^2)二次方法;如果对包含100个元素的列表执行此操作,将进行100.000次比较。对于包含1.000.000个元素的列表,这将是1.000.000.000个比较。@martijn pieters感谢您的评论。我已经更新了我的帖子,还有什么评论吗?
list.index()
仍然是一个O(N)步骤。这看起来只是一个命令,但是Python仍然需要扫描列表以找到第一个匹配项并返回索引。这是非常低效的。这是一个O(N^2)二次方法;如果对包含100个元素的列表执行此操作,将进行100.000次比较。对于包含1.000.000个元素的列表,这将是1.000.000.000个比较。@martijn pieters感谢您的评论。我已经更新了我的帖子,还有什么评论吗?
list.index()
仍然是一个O(N)步骤。对您来说,它看起来只是一个命令,但Python仍然需要扫描列表以找到第一个匹配项并返回索引。我看不出有任何理由使用
排序的
解决方案我看不到有任何理由在
列表(…)中使用
排序的
解决方案包装
[None]*len(A)
一无所获包装
[None]*len(A)
列表中(…)
一无所获