Christian
Christian

Reputation: 749

python: multidimensional sorting of class object

is there a way to sort a list first for x, than y and than z. I'm not sure if my code will do it: (ch is a object with the attribut left_edge)

ch.sort(cmp=lambda x,y: cmp(x.left_edge[0], y.left_edge[0]))
ch.sort(cmp=lambda x,y: cmp(x.left_edge[1], y.left_edge[1]))
ch.sort(cmp=lambda x,y: cmp(x.left_edge[2], y.left_edge[2]))

Simple example:

unsorted
(1,1,2),(2,1,1),(1,1,3),(2,1,2)
sorted
(1,1,2),(1,1,3),(2,1,1),(2,1,2)

but I need the sorted objects...

Upvotes: 1

Views: 87

Answers (2)

Duncan
Duncan

Reputation: 95652

You should avoid using the cmp argument to sort: if you ever want to upgrade to Python 3.x you'll find it no longer exists. Use the key argument instead:

ch.sort(key=lambda x: x.left_edge)

If, as it appears the left_edge attribute is simply a list or tuple then just use it directly as the key value and it should all work. If it is something unusual that is subscriptable but doesn't compare then build the tuple:

ch.sort(key=lambda x: (x.left_edge[0],x.left_edge[1],x.left_edge[2]))

Upvotes: 1

icecrime
icecrime

Reputation: 76755

That is exactly how the default tuple comparer works:

>>> l = [(1, 1, 2), (2, 1, 1), (1, 1, 3), (2, 1, 2)]
>>> sorted(l)
[(1, 1, 2), (1, 1, 3), (2, 1, 1), (2, 1, 2)]

See the comparison description in the documentation:

Comparison of objects of the same type depends on the type:

  • Tuples and lists are compared lexicographically using comparison of corresponding elements. This means that to compare equal, each element must compare equal and the two sequences must be of the same type and have the same length.

    If not equal, the sequences are ordered the same as their first differing elements. For example, cmp([1,2,x], [1,2,y]) returns the same as cmp(x,y). If the corresponding element does not exist, the shorter sequence is ordered first (for example, [1,2] < [1,2,3]).

Upvotes: 7

Related Questions