sorting a list of lists

N

nicksavill

Hi,

i would like to sort a list of lists. The list is first sorted on the
second item in the sub-lists (which I can do), then on the third item
(which I can't).

eg. records = [['dog',1,2], ['chair',2,1], ['cat',1,3], ['horse',3,4],
['table',3,2], ['window',3,5]]

I want sorted to [['dog',1,2], ['cat',1,3], ['chair',2,1], ['table',
3,2], ['horse',3,4], ['window',3,5]]

To sort on the second item in the sub-lists I do the following

pass1 = itemgetter(1)
sorted(records, key=pass1)

How can I then sort on the third item in the sub-lists whilst keeping
the order on the second item?

Nick

P

Peter Otten

i would like to sort a list of lists. The list is first sorted on the
second item in the sub-lists (which I can do), then on the third item
(which I can't).

eg. records = [['dog',1,2], ['chair',2,1], ['cat',1,3], ['horse',3,4],
['table',3,2], ['window',3,5]]

I want sorted to [['dog',1,2], ['cat',1,3], ['chair',2,1], ['table',
3,2], ['horse',3,4], ['window',3,5]]

To sort on the second item in the sub-lists I do the following

pass1 = itemgetter(1)
sorted(records, key=pass1)

How can I then sort on the third item in the sub-lists whilst keeping
the order on the second item?

list.sort() is stable, so

items = sorted(records, key=itemgetter(2)) # minor order first
items.sort(key=itemgetter(1)) # major order

should give the desired result (items with equal item[1] are sorted by
item[2]. Python 2.5 also allows to pass multiple indices to itemgetter()

sorted(records, key=itemgetter(1, 2))

IIRC for Python 2.4 you'd have to write your own key routine:

def key(item):
return item[1], item[2]
sorted(records, key=key)

Peter

I

iapain

i would like to sort a list of lists. The list is first sorted on the
second item in the sub-lists (which I can do), then on the third item
(which I can't).

Write a comparator instead of dirty hacks

mylistoflist.sort(mycomparator)

def mycomparator(a, b):
#do

S

Stefan Behnel

iapain said:
Write a comparator instead of dirty hacks

mylistoflist.sort(mycomparator)

def mycomparator(a, b):
#do

Taking advantage of stable sorting is totally not a hack. The OP just tried
the two sorting steps in the wrong order.

Stefan

I

iapain

Taking advantage of stable sorting is totally not a hack. The OP just tried
the two sorting steps in the wrong order.

I didnt say not to use stable sorting, but write a generic function
and hacky code. It is always better to adopt a generic approach.

D

drobinow

... It is always better to adopt a generic approach.

The above statement is incorrect.

T

Tuomas

records = [['dog',1,2], ['chair',2,1], ['cat',1,3], ['horse',3,4],
.... ['table',3,2], ['window',3,5]]
>>> sorted(records, key = lambda x: (x[1], x[2]))
[['dog', 1, 2], ['cat', 1, 3], ['chair', 2, 1], ['table', 3, 2],
['horse', 3, 4], ['window', 3, 5]]

Hi,

i would like to sort a list of lists. The list is first sorted on the
second item in the sub-lists (which I can do), then on the third item
(which I can't).

eg. records = [['dog',1,2], ['chair',2,1], ['cat',1,3], ['horse',3,4],
['table',3,2], ['window',3,5]]

I want sorted to [['dog',1,2], ['cat',1,3], ['chair',2,1], ['table',
3,2], ['horse',3,4], ['window',3,5]]

To sort on the second item in the sub-lists I do the following

pass1 = itemgetter(1)
sorted(records, key=pass1)

How can I then sort on the third item in the sub-lists whilst keeping
the order on the second item?

Nick

G

Gabriel Genellina

I didnt say not to use stable sorting, but write a generic function
and hacky code. It is always better to adopt a generic approach.

Sorting on multiple keys from last to first has been the "standard" and
"generic" approach even before computers existed. Hollerith punched cards
"processors" did it that way around 1890.

N

nicksavill

Thanks guys,

"dirty hack" was what I needed to get a job done quickly.

Nick