4

I am trying to sort a list of tuples, on the first element of the tuple, using a custom pre-defined list as the desired order. So I have the list as

my_list=(['chr1',12],['chrX',32],['chr2',1],['chr1',79],['chr2',6])

and the predefined list on the first element is

custom_list=['chr1','chr2','chrX']

I want the output to be

(['chr1',12],['chr1',79],['chr2',1],['chr2',6],['chrX',32])

(For now, sorting on the second element is not needed.) I can't figure out how to do this . Can anyone help please?

1
  • 5
    You have there a tuple of lists, not a list of tuples. Commented Oct 10, 2013 at 22:05

1 Answer 1

7

You can use the list.index() function to turn position in the custom_list into a sort key:

sorted(my_list, key=lambda x: (custom_list.index(x[0]), x[1]))

You may want to turn your custom_list into a dictionary however, for faster mapping:

custom_list_indices = {v: i for i, v in enumerate(custom_list)}
sorted(my_list, key=lambda x: (custom_list_indices.get(x[0]), x[1]))

Dictionary lookups take constant time, list.index() time is directly proportional to the length of the list.

Another advantage is that with a dictionary, you can return a default value for entries not found in the dictionary (None in this example); list.index() will raise a ValueError exception instead.

Demo:

>>> my_list=(['chr1',12],['chrX',32],['chr2',1],['chr1',79],['chr2',6])
>>> custom_list=['chr1','chr2','chrX']
>>> sorted(my_list, key=lambda x: (custom_list.index(x[0]), x[1]))
[['chr1', 12], ['chr1', 79], ['chr2', 1], ['chr2', 6], ['chrX', 32]]
>>> custom_list_indices = {v: i for i, v in enumerate(custom_list)}
>>> sorted(my_list, key=lambda x: (custom_list_indices.get(x[0]), x[1]))
[['chr1', 12], ['chr1', 79], ['chr2', 1], ['chr2', 6], ['chrX', 32]]
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks so much for this. How about the case where instead of a list of tuples, I have a list of objects? And I want to sort on a field in that object on the custom_list array?

Your Answer

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.