Given an arbitrary array of size n , I'd like to reorganize the elements of the array based on the array's discrete indices. Python example:
# Unique array of size n [ "a", "b", "c", "d", "e", . ] # Indices of array [ 0, 1, 2, 3, 4, . ] # Desired re-organization function 'indexMove' indexMove( [ "a", "b", "c", "d", "e", . ], [ , 4, 0, 2, 3, . 1 ] ) # Desired output from indexMove operation [ , "e", "a", "c", "d", . "b" ]
What is the fastest way to perform this operation (achieving the smallest time complexity)?
16.9k 5 5 gold badges 84 84 silver badges 106 106 bronze badges
asked Feb 1, 2010 at 15:08
54.6k 56 56 gold badges 152 152 silver badges 183 183 bronze badges
Probably duplicate of stackoverflow.com/questions/976882/…
Commented Feb 1, 2010 at 15:11
Without specifying how you want to order the items its hard to answer. Do you want to sort them? Shuffle them? Remove some of them?
Commented Feb 1, 2010 at 15:13@tvanfosson: In this case, arbitrary could also mean: take an arbitrary (but well defined) sort function.
Commented Feb 1, 2010 at 15:18 @mizipzor I want to re-order them in a predefined way. (Edited the question to clarify this) Commented Feb 1, 2010 at 15:22@SilentGhost It will have a new index. May be 4. The point is that I know the new order of the items.
Commented Feb 1, 2010 at 15:24You can do it like this
mylist = ['a', 'b', 'c', 'd', 'e'] myorder = [3, 2, 0, 1, 4] mylist = [mylist[i] for i in myorder] print(mylist) # prints: ['d', 'c', 'a', 'b', 'e']
16.9k 5 5 gold badges 84 84 silver badges 106 106 bronze badges
answered Feb 1, 2010 at 15:10
28.1k 19 19 gold badges 85 85 silver badges 95 95 bronze badges
This creates a new variable. How to re-order a list in-place? Thanks
Commented Aug 19, 2019 at 14:09
@Confounded Simply change the final line to: mylist[:] = [mylist[i] for i in myorder]
Commented Mar 1, 2020 at 12:35
@Adam Thanks! What's the time and space complexity of this operation? Does it iterate over mylist when assigning entries from [mylist[i] for i in myorder] to mylist[:] ?
Commented Oct 1, 2020 at 18:05Hey, I am new to Python and I am curious how does this line of code "[mylist[i] for i in myorder]" work? I have only learnt the basic for loop.
Commented Dec 4, 2020 at 21:15Wow, oldie but a goodie. Thanks for taking me back @ZionAdams. Check out List Comprehensions: realpython.com/list-comprehension-python/…
Commented Dec 5, 2020 at 2:11>>> a = [1, 2, 3] >>> a[0], a[2] = a[2], a[0] >>> a [3, 2, 1]
answered Feb 1, 2010 at 15:23
SilentGhost SilentGhost
317k 67 67 gold badges 309 309 silver badges 293 293 bronze badges
I just could not understand the syntax until I realized is a pairwise simultaneous assignment. ´:-)
Commented Apr 27, 2020 at 9:56
>>> import random >>> x = [1,2,3,4,5] >>> random.shuffle(x) >>> x [5, 2, 4, 3, 1]
answered Feb 1, 2010 at 15:11
108k 20 20 gold badges 177 177 silver badges 234 234 bronze badges
@wenlibin02, just ran it under 2.7.5 and it still works just fine. Do you get some sort of error?
Commented Jul 20, 2015 at 2:44
no error, I just type: 1) import random; x = [1, 2, 3]; random.shuffle(x); #it returns None; and 2) I tried np.random.shuffle. the results are the same.
Commented Jul 20, 2015 at 7:30Oh, sorry! I did not realize that I directly change the value of x. It did return None. And it works. Thanks.
Commented Jul 20, 2015 at 7:33Is the final order defined by a list of indices ?
>>> items = [1, None, "chicken", int] >>> order = [3, 0, 1, 2] >>> ordered_list = [items[i] for i in order] >>> ordered_list [, 1, None, 'chicken']
1 1 1 silver badge
answered Feb 1, 2010 at 15:27
Raphaël Saint-Pierre Raphaël Saint-Pierre
2,556 1 1 gold badge 20 20 silver badges 24 24 bronze badges
>>> a=["a","b","c","d","e"] >>> a[0],a[3] = a[3],a[0] >>> a ['d', 'b', 'c', 'a', 'e']
answered Feb 1, 2010 at 15:24
ghostdog74 ghostdog74
339k 60 60 gold badges 261 261 silver badges 348 348 bronze badges
You can provide your own sort function to list.sort() :
@SilentGhost: This is meant as a general answer. In the OPs case your answer is more appropriate. Nevertheless I think it is important to know that a generic solution exists.
Commented Feb 1, 2010 at 16:41If you use numpy there's a neat way to do it:
items = np.array(["a","b","c","d"]) indices = np.arange(items.shape[0]) np.random.shuffle(indices) print(indices) print(items[indices])
This code returns:
[1 3 2 0] ['b' 'd' 'c' 'a']
answered Jul 18, 2018 at 10:56
user2228129 user2228129
31 1 1 bronze badge
OP is looking for a specific reordering, not a generic shuffling.
Commented Mar 13, 2019 at 5:42
If you do not care so much about efficiency, you could rely on numpy's array indexing to make it elegant:
a = ['123', 'abc', 456] order = [2, 0, 1] a2 = list( np.array(a, dtype=object)[order] )
answered Nov 2, 2018 at 8:52
Shaohua Li Shaohua Li
399 3 3 silver badges 9 9 bronze badges
One more thing which can be considered is the other interpretation as pointed out by darkless
Code in Python 2.7
mylist = ['a', 'b', 'c', 'd', 'e'] myorder = [3, 2, 0, 1, 4] mylist = sorted(zip(mylist, myorder), key=lambda x: x[1]) print [item[0] for item in mylist]
This will print ['c', 'd', 'b', 'a', 'e']
answered Dec 5, 2017 at 12:53 Kshitij Satpute Kshitij Satpute 29 4 4 bronze badgesFrom what I understand of your question, it appears that you want to apply a permutation that you specify on a list . This is done by specifying another list (lets call it p ) that holds the indices of the elements of the original list that should appear in the permuted list . You then use p to make a new list by simply substituting the element at each position by that whose index is in that position in p .
def apply_permutation(lst, p): return [lst[x] for x in p] arr=list("abcde") new_order=[3,2,0,1,4] print apply_permutation(arr,new_order)
This prints ['d', 'c', 'a', 'b', 'e'] .
This actually creates a new list , but it can be trivially modified to permute the original "in place".