On 16 Apr 2009, at 11:33, Jacob Holm wrote:
_marker = object()
def min(*args, **kwargs): # extract and validate kwargs initial = kwargs.pop('initial', _marker) default = kwargs.pop('default', _marker) key = kwargs.pop('key', _marker) if kwargs: raise TypeError('min() got an unexpected keyword argument') # validate args, this TypeError is needed for backwards compatibility if initial is _marker and default is _marker and not args: raise TypeError('min expected 1 arguments, got 0') # create iterator for the values if len(args) == 1: it = iter(args[0]) else: it = iter(args) # extract first value if any and handle empty sequence if initial is not _marker: result = initial else: for result in it: break else: if default is _marker: raise ValueError('min() arg is an empty sequence') return default # handle remaining values if key is _marker: for value in it: if value < result: result = value else: resultkey = key(result) for value in it: valuekey = key(value) if valuekey < resultkey: result, resultkey = value, valuekey return result
I made a similar implementation, that I post here FWIW (using positional only arguments makes it slighly more compact): _not_provided = object() def min(first, *rest, key=_not_provided, default=_not_provided): if not rest: rest = iter(first) for first in rest: break else: if default is _not_provided: raise ValueError("min() arg is an empty sequence") else: return default if key is _not_provided: for el in rest: if el < first: first = el else: fkey = key(first) for el in rest: elkey = key(el) if elkey < fkey: first, fkey = el, elkey return first