简体   繁体   English

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

[英]Swapping indices with values in a Python list?

(No, this is not a homework assignment nor a contest, even though it might look like one.) (不,这不是家庭作业,也不是竞赛,即使看起来像一个。)

I have a list A in Python that contains the numbers range(0, len(A)) . 我在Python中有一个列表A ,其中包含数字range(0, len(A)) The numbers are not in order, but all of them exist in the list. 这些数字不是按顺序排列的,但是它们都存在于列表中。

I'm looking for a simple way to build a list B where the indices and values have been swapped, ie a list that, for each integer n , contains the position of n in A . 我正在寻找一种构建列表B的简单方法,在该列表中索引和值已被交换,即对于每个整数n ,列表nA中的位置都包含A

Example: 例:

A = [0, 4, 1, 3, 2]
B = [0, 2, 4, 3, 1]

I can put the code to generate B either separately or in the code that generates A . 我可以将代码单独生成B也可以放在生成A的代码中。 In particular, here's how I generate A : 特别是,这是我生成A

A = [value(i) for i in range(length)]

What would be the best way to do this? 最好的方法是什么?

How about assigning to the pre-allocated B: 如何分配给预分配的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]

That would be O(n). 那将是O(n)。

Using the enumerate() function to decorate each value with their index, sorting with sorted() on the values, and then un-decorate again to extract the indices in value order: 使用enumerate()函数用索引装饰每个值,对值进行sorted() ,然后再次取消修饰以按值顺序提取索引:

[i for i, v in sorted(enumerate(A), key=lambda iv: iv[1])]

This has a O(NlogN) time complexity because we used sorting. 因为我们使用了排序,所以这具有O(NlogN)时间复杂度。

Demo: 演示:

>>> A = [0, 4, 1, 3, 2]
>>> [i for i, v in sorted(enumerate(A), key=lambda iv: iv[1])]
[0, 2, 4, 3, 1]

We can also use a pre-built list to assign indices to for a O(N) solution: 我们还可以使用预先构建的列表为O(N)解决方案分配索引:

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

Demo: 演示:

>>> B = [0] * len(A)
>>> for i, v in enumerate(A):
...     B[v] = i
... 
>>> B
[0, 2, 4, 3, 1]

This is probably the better option if time complexity is of a big issue; 如果时间复杂度是一个大问题,那么这可能是更好的选择。 for N = 100 the sorting approach will take about 461 steps vs. 100 for the pre-built list approach. 对于N = 100,排序方法大约需要461个步骤,而预建列表方法则需要100个步骤。

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] 分辨率: [0, 2, 4, 3, 1] 0,2,4,3,1 [0, 2, 4, 3, 1]

This is very naive; 这很幼稚。

[ [ x[0] for x in enumerate(A) if x[1] == i][0] for i in range(len(A)) ]

This works perfect, 这很完美,

[A.index(A.index(i)) for i in A]  

This is better ; 更好 ;

[A.index(i[0]) for i in enumerate(A)]

This one beats the other; 这个击败了另一个。

[A.index(i) for i in range(len(A))]

Proof; 证明;

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM