Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting list based on values from another list

I have a list of strings like this:

X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"] Y = [ 0,   1,   1,   0,   1,   2,   2,   0,   1 ] 

What is the shortest way of sorting X using values from Y to get the following output?

["a", "d", "h", "b", "c", "e", "i", "f", "g"] 

The order of the elements having the same "key" does not matter. I can resort to the use of for constructs but I am curious if there is a shorter way. Any suggestions?

like image 315
Legend Avatar asked Jul 07 '11 23:07

Legend


People also ask

How do I sort a list by another list in Python?

Use the zip() and sorted() Functions to Sort the List Based on Another List in Python. In this method, we will use the zip() function to create a third object by combining the two given lists, the first which has to be sorted and the second on which the sorting depends.


2 Answers

Shortest Code

[x for _, x in sorted(zip(Y, X))] 

Example:

X = ["a", "b", "c", "d", "e", "f", "g", "h", "i"] Y = [ 0,   1,   1,    0,   1,   2,   2,   0,   1]  Z = [x for _,x in sorted(zip(Y,X))] print(Z)  # ["a", "d", "h", "b", "c", "e", "i", "f", "g"] 

Generally Speaking

[x for _, x in sorted(zip(Y, X), key=lambda pair: pair[0])] 

Explained:

  1. zip the two lists.
  2. create a new, sorted list based on the zip using sorted().
  3. using a list comprehension extract the first elements of each pair from the sorted, zipped list.

For more information on how to set\use the key parameter as well as the sorted function in general, take a look at this.


like image 138
Whatang Avatar answered Oct 03 '22 08:10

Whatang


Zip the two lists together, sort it, then take the parts you want:

>>> yx = zip(Y, X) >>> yx [(0, 'a'), (1, 'b'), (1, 'c'), (0, 'd'), (1, 'e'), (2, 'f'), (2, 'g'), (0, 'h'), (1, 'i')] >>> yx.sort() >>> yx [(0, 'a'), (0, 'd'), (0, 'h'), (1, 'b'), (1, 'c'), (1, 'e'), (1, 'i'), (2, 'f'), (2, 'g')] >>> x_sorted = [x for y, x in yx] >>> x_sorted ['a', 'd', 'h', 'b', 'c', 'e', 'i', 'f', 'g'] 

Combine these together to get:

[x for y, x in sorted(zip(Y, X))] 
like image 20
Ned Batchelder Avatar answered Oct 03 '22 09:10

Ned Batchelder