6

I would like to sort a list in Python based on a pre-sorted list.

presorted_list = ['2C','3C','4C','2D','3D','4D']
unsorted_list = ['3D','2C','4D','2D']

How can I sort unsorted_list such that the values appear in the same order that presorted_list has them? That is, in this case the sorted result should be ['2C','2D','3D','4D'].

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
  • https://stackoverflow.com/questions/9764298 is another way of sorting one list "based on" another list - a completely different problem that is sometimes, unfortunately, described with very similar language. – Karl Knechtel Mar 02 '23 at 06:04

1 Answers1

6
In [5]: sorted(unsorted_list, key=presorted_list.index)
Out[5]: ['2C', '2D', '3D', '4D']

or, for better performance (particularly when len(presorted_list) is large),

In [6]: order = {item:i for i, item in enumerate(presorted_list)}    
In [7]: sorted(unsorted_list, key=order.__getitem__)
Out[7]: ['2C', '2D', '3D', '4D']

For more on how to sort using keys, see the excellent Howto Sort wiki.


If unsorted_list contains items (such as '6D') not in presorted_list then the above methods will raise an error. You first have to decide how you want to sort these items. If you want them placed at the end of the list, you could use

In [10]: unsorted_list = ['3D','2C','6D','4D','2D']

In [11]: sorted(unsorted_list, key=lambda x: order.get(x, float('inf')))
Out[11]: ['2C', '2D', '3D', '4D', '6D']

or if you wish to place such items at the front of the list, use

In [12]: sorted(unsorted_list, key=lambda x: order.get(x, -1))
Out[12]: ['6D', '2C', '2D', '3D', '4D']
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • I'm sorry, I'm new to this, but the first bit of code seems to give me a Value Error for the very first item in the unsorted list. ValueError: '6D' is not in list – Danica Fernandes Apr 09 '16 at 15:34
  • `.index` will raise a value error if the item is not in the presorted_list. – Tadhg McDonald-Jensen Apr 09 '16 at 15:37
  • @Danica: If you want items _removed_ that aren't in the `presorted_list`, use something like `sorted(itertools.ifilter(lambda x: x in presorted_list, unsorted_list), key=order.__getitem__)`. – martineau Apr 09 '16 at 16:08
  • The item is part of the presorted list, and it still says that it isnt, I'm not too sure why. Here is the unsorted list: ['8S', 'JD', 'AC', '5C', '8D', '10C'] Here is the sorted list: ['2C','3C','4C','5C','6C','7C','8C','9C','10C','JC','QC','KC','AC', '2D','3D','4D','5D','6D','7D','8D','9D','10D','JD','QD','KD','AD', '2H','3H','4H','5H','6H','7H','8H','9H','10H','JH','QH','KH','AH', '2S','3S','4S','5S','6S','7S','8S','9S','10S','JS','QS','KS','AS'] And the error is ValueError: '8S' is not in list – Danica Fernandes Apr 09 '16 at 16:14