用 Python 列表中的值交换索引?
Swapping indices with values in a Python list?
(不,这不是家庭作业也不是竞赛,尽管它看起来像一个。)
我在 Python 中有一个列表 A
,其中包含数字 range(0, len(A))
。数字不分先后,但都在列表中。
我正在寻找一种简单的方法来构建列表 B
,其中交换了索引和值,即对于每个整数 n
,包含 [的位置的列表=16=] 在 A
.
示例:
A = [0, 4, 1, 3, 2]
B = [0, 2, 4, 3, 1]
我可以将生成 B
的代码单独放在生成 A
的代码中。特别是,这是我生成 A
:
的方式
A = [value(i) for i in range(length)]
执行此操作的最佳方法是什么?
在值上使用 enumerate()
function to decorate each value with their index, sorting with 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 个步骤。
如何分配给预分配的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)。
A = [0, 4, 1, 3, 2]
B = [None]*len(A)
for i, x in enumerate(A):
B[x] = i
print B
结果:[0, 2, 4, 3, 1]
这太天真了;
[ [ 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
(不,这不是家庭作业也不是竞赛,尽管它看起来像一个。)
我在 Python 中有一个列表 A
,其中包含数字 range(0, len(A))
。数字不分先后,但都在列表中。
我正在寻找一种简单的方法来构建列表 B
,其中交换了索引和值,即对于每个整数 n
,包含 [的位置的列表=16=] 在 A
.
示例:
A = [0, 4, 1, 3, 2]
B = [0, 2, 4, 3, 1]
我可以将生成 B
的代码单独放在生成 A
的代码中。特别是,这是我生成 A
:
A = [value(i) for i in range(length)]
执行此操作的最佳方法是什么?
在值上使用 enumerate()
function to decorate each value with their index, sorting with 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 个步骤。
如何分配给预分配的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)。
A = [0, 4, 1, 3, 2]
B = [None]*len(A)
for i, x in enumerate(A):
B[x] = i
print B
结果:[0, 2, 4, 3, 1]
这太天真了;
[ [ 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