How can I reorder a list? [closed]

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:24

12 Answers 12

You 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:05

Hey, 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:15

Wow, 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:30

Oh, 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:33

Is 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() :

1 1 1 silver badge answered Feb 1, 2010 at 16:06 Felix Kling Felix Kling 812k 176 176 gold badges 1.1k 1.1k silver badges 1.2k 1.2k bronze badges and how exactly you'd implement this? Commented Feb 1, 2010 at 16:10

@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:41

If 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

  1. Reorder by value - Already solved by AJ above
  2. Reorder by index

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 badges

From 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".