Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to sort list with custom sorting parameters in Python?

I have a series of lists that looks like this:

li1 = ['a.1', 'b.9', 'c.8', 'd.1', 'e.2']
li2 = ['a.4', 'b.1', 'c.2', 'd.2', 'e.4']

How can I rearrange the items in each list so that the first item is 'b.something'? For the example above:

li1 = ['b.9', 'a.1', 'c.8', 'd.1', 'e.2']
li2 = ['b.1', 'a.4', 'c.2', 'd.2', 'e.4']

Maintaining the order after the first item isn't important. Thanks for the help.

like image 293
drbunsen Avatar asked Nov 03 '11 14:11

drbunsen


2 Answers

Python's sorting is stable, so you will maintain the order after the first item regardless.

li1.sort(key=lambda x: not x.startswith('b.'))
like image 69
Ignacio Vazquez-Abrams Avatar answered Nov 14 '22 22:11

Ignacio Vazquez-Abrams


rearrange the items in each list so that the first item is 'b.something'

Maintaining the order after the first item isn't important.

That isn't sorting, then. Conceptually, you're just trying to bring that element to the front.

In other words, you want a list that consists of that element, followed by everything that isn't that element. Fudging this a little for the case where there are multiple b.somethings, and noting that we don't care what happens as long as the first element is a b.something, we can rephrase that: a list of every element meeting the condition ("starts with b."), followed by every element not meeting the condition. (This is sometimes called partitioning; see for example std::partition in C++.)

In Python, this is as simple as describing those two list-components with list comprehensions and sticking them together:

[x for x in li if x.startswith('b.')] + [x for x in li if not x.startswith('b.')]

...Or you can pretend that you're sorting, just with a bunch of elements that really only have two values after the key is applied, and apply the appropriate key, as in Ignacio Vasquez-Abrams' answer.

like image 33
Karl Knechtel Avatar answered Nov 14 '22 23:11

Karl Knechtel