Reputation: 55
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
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
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
Reputation: 799390
Use the index as the key.
key=lambda x: customlist.index(x)
Upvotes: 5