min() with custom compare.

Jeff Epler jepler at unpythonic.net
Wed Apr 7 08:56:22 EDT 2004


Use DSU, as for sorts.  Turn each element i of the sequence into a tuple
(f(i), i), and find the min of that sequence.  Return element 1 of that
tuple, which is the original set element.


    def min_f(seq, f):
        decorated = [(f(i), i) for i in seq]
        return min(decorated)[1]

    def max_f(seq, f):
        decorated = [(f(i), i) for i in seq]
        return min(decorated)[1]

>>> l=[5,-4,1,9,-9]
>>> min(l)
-9
>>> min_f(l, abs)
1

You can make 'decorated' be a generator and avoid the need to hold the
whole list in memory:

    def decorated2(seq, f):
        for i in seq:
            yield f(i), i

    def min_f2(seq, f):
        return min(decorated(seq, f))[1]

    def max_f2(seq, f):
        return max(decorated(seq, f))[1]

If you want to break ties not by comparing the original items but by
comparing indices, you could do this:
    def decorated3(seq, f):
        for i, v in enumerate(seq):
            yield (f(v), i, v)

    def min_f3(seq, f):
        return min(decorated3(seq, f))[2]

Jeff




More information about the Python-list mailing list