mensah
mensah

Reputation: 55

Custom sort order of list

I have lists such as:

mylist1 = ['alpha', 'green']
mylist2 = ['blue', 'alpha', 'red']

I want to sort these two lists by this custom ordered list: ['red','blue','green','alpha']

so that mylist1 = ['green', 'alpha'] and mylist2 = ['red','blue','alpha']

How can i do this in Python?

Upvotes: 6

Views: 1957

Answers (3)

Jon Clements
Jon Clements

Reputation: 142226

You could use:

>>> a = ['red','blue','green','alpha']
>>> b = ['alpha', 'green']
>>> filter(set(b).__contains__, a)
['green', 'alpha']

Instead of sorting the list into an order, we only include elements from the already ordered list a that are present in the source list b.

You could write that as [el for el in a if el in b] and optionally have b as a set if desired.

Of course, If you really wanted to sort it, then you should probably build an index lookup rather than potentially iterate the list multiple times (by keep issuing .index):

order = {v:i for i,v in enumerate(a)}
b.sort(key=order.get)

Upvotes: 2

Claudiu
Claudiu

Reputation: 229561

Demonstration:

>>> mylist1 = ['alpha', 'green']
>>> mylist2 = ['blue', 'alpha', 'red']
>>> sort_order = ['red', 'blue', 'green', 'alpha']
>>> mylist1.sort(key=sort_order.index)
>>> mylist1
['green', 'alpha']
>>> mylist2.sort(key=sort_order.index)
>>> mylist2
['red', 'blue', 'alpha']

Explanation:

The key parameter in list.sort causes the list to determine the order by comparing key(element) instead of element. For example, to do case-insensitive sort, you can pass a key function which makes the string lowercase. The lowercase elements are compared, but the original elements are preserved:

>>> x = ["age", "Bonkers", "cheese"]
>>> x.sort()
>>> x
['Bonkers', 'age', 'cheese']
>>> str.lower("Bonkers")
'bonkers'    
>>> x.sort(key=str.lower)
>>> x
['age', 'Bonkers', 'cheese']

Using sort_order.index for the key uses the index that element has in the sort_order list to determine the order instead of the element itself. So 'red' uses 0, 'blue' uses 1, etc... the result is that the list to be sorted gets sorted according to where each element is in sort_order.

Upvotes: 14

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 799390

Use the index as the key.

key=lambda x: customlist.index(x)

Upvotes: 5

Related Questions