In an earlier tip, you learned how to sort iterables based on a key. You can use a sequence like list or tuple to specify a tie-breaker condition when two or more items are deemed equal under the primary sorting rule.

>>> books = ('Mage Errant', 'Piranesi', 'Cradle', 'The Weirkey Chronicles', 'Mistborn')

# sorts based on the number of words
# retains original order for items with the same number of words
>>> sorted(books, key=lambda b: b.count(' '))
['Piranesi', 'Cradle', 'Mistborn', 'Mage Errant', 'The Weirkey Chronicles']

# items with the same number of words are further sorted in alphabetic order
>>> sorted(books, key=lambda b: (b.count(' '), b))
['Cradle', 'Mistborn', 'Piranesi', 'Mage Errant', 'The Weirkey Chronicles']

To sort in descending order, usually the reverse=True keyword argument is used. But what if the primary and secondary rules are opposites? If one of the rule is numerical in nature, you can simply negate the number to reverse the order.

# descending order based on the number of words
# ascending alphabetic order for items with the same number of words
>>> sorted(books, key=lambda b: (-b.count(' '), b))
['The Weirkey Chronicles', 'Mage Errant', 'Cradle', 'Mistborn', 'Piranesi']

# reverse the above result
>>> sorted(books, key=lambda b: (-b.count(' '), b), reverse=True)
['Piranesi', 'Mistborn', 'Cradle', 'Mage Errant', 'The Weirkey Chronicles']

info See also docs.python HOWTOs: Sorting.

Video demo:


info See also my 100 Page Python Intro ebook.