0

I am trying to permute an array based on values from another array. A = [5, 6, 7, 8] P = [1, 3 ,2, 0] Should return [6, 8, 7, 5]

I have the below code written in python. I wanted to see if this is an acceptable approach to this problem or if there are better ways to solve this problem

def permute(A, P):
 for i in range(len(P)):
 if i != P[i]:
 if int(P[P[i]]) >= 0:
 if A[i]>0:
 A[i], P[i]=A[P[i]], -A[i]
 else:
 A[i], P[i] = A[P[i]], f"{A[i]}"
 else:
 if isinstance(P[P[i]],int):
 A[i], P[i] = -P[P[i]], -A[i]
 else:
 A[i], P[i] = int(P[P[i]]), f"{A[i]}"
 return(A)

I store the original value from A as a negative value in P so i can retrieve it back by changing the sign. However I am doing a string convert if the value in the original array is negative to keep a track of when the values are negative vs when i store them as negative in P.

This code works but looking for ideas on if this can be done in a much cleaner way

asked Jul 2, 2020 at 5:17
5
  • 3
    Seems like [A[i] for i in P ] would be a bit easier. Commented Jul 2, 2020 at 5:20
  • what's all this about negative values and string conversion? why does it matter what value they have if all you're doing is shifting positions in the list? Commented Jul 2, 2020 at 5:21
  • Looks like OP is trying to permute A in-place Commented Jul 2, 2020 at 5:22
  • @HansMusgrave still doesn't make sense. Even if it was meant to be a "reversible" permutation or in-place, both tasks shouldn't require manipulating the values based on what value (sign) and type they are Commented Jul 2, 2020 at 5:23
  • Yes i think i overlooked i am able to swap without changing the signs or string convert Commented Jul 3, 2020 at 17:37

4 Answers 4

1

In-place copying, using P to track original values. Copies original values swapped to P. If index value in P already iterated over, use P, else use value in A (to check if it has been overwritten yet).

A = [5, 6, 7, 8]
P = [1, 3 ,2, 0]
for i,p in enumerate(P):
 P[i]=A[i]
 A[i]=P[p] if p < i else A[p]

It would have been even simpler to just copy values to P directly if you need in-place without creating a list (slightly more efficient in both time and space as well), and use P as the new A, but it seems like you want to do it in-place on A for some reason, and only use P as a temporary store.

List comprehension is also simpler to implement, and creates a copy without mutating the lists.

Difference in efficiency shouldn't ever really matter. Even if you're dealing with extremely large lists in resource constrained situations, it's not likely to ever be a noticeable difference, let alone be the bottleneck.

answered Jul 2, 2020 at 5:37
0

If I understand correctly, isn't this what you want?

A = [5, 6, 7, 8]
P = [1, 3 ,2, 0]
for i in range(len(P)):
 print(A[P[i]])
answered Jul 2, 2020 at 5:23
0

Seems straigt forward to use list comprihension:

A = [5, 6, 7, 8]
P = [1, 3 ,2, 0]
print([A[i] for i in P ])

Also, if you use a numpy array istead, you can simply use the P array as indexing for the new list:

import numpy as np
A = np.array([5, 6, 7, 8])
P = [1, 3 ,2, 0]
print(A[P])

Also giving the correct answer.

answered Jul 2, 2020 at 5:24
0

I think i should have mentioned this earlier, the solutions is to update list in place and so i cannot do prints. But i was able to come up with a better algorithm to update without changing signs or string convert

def permute(A, P):
 for i in range(len(P)):
 if i != P[i]:
 if P[i] >= i:
 A[i], P[i]=A[P[i]], A[i]
 else:
 A[i], P[i] = P[P[i]]
 return P 
answered Jul 3, 2020 at 17:42
1
  • fyi if you look at my answer, it is actually a simplified version of what you have here except that mine purposely keeps the final result in A to stay true to your original code. If you are okay with mutating P as you have done here, you actually don't need any conditional branching at all. You can just do one loop of P[i]=A[P[i]] and return P, which is what I was referring to in the second paragraph. Commented Jul 4, 2020 at 9:42

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.