Here's a function that will apply multiple keys economically to find the minimum of a list of elements. It might be useful to fight the canonical battles:
def lazymin(seq, keys):
"""Return minimum item using one or more keys that are provided in
the list, applying keys only when necessary.
Examples
========
>>> from sympy.utilities.iterables import lazymin
>>> from sympy import S
>>> lazymin(range(20)+[S.Zero], keys=[int, hash])
[0]
>>> type(_[0])
<class 'sympy.core.numbers.Zero'>
"""
from collections import defaultdict
if not seq:
raise ValueError('empty sequence')
while True:
if len(seq) == 1:
return seq[0]
if not keys:
raise ValueError("not enough keys to resolve min element")
k = keys.pop() # error will be raised if we run out
d=defaultdict(list)
for s in seq:
d[k(s)].append(s)
seq = d[min(d)]
The first key is applied and if there is a tie for first place, the next key is applied only to those that tied, etc... until keys are exhausted or there is a winner.