[Python-ideas] 'default' keyword argument for max(), min()

Raymond Hettinger python at rcn.com
Thu Apr 16 20:57:42 CEST 2009

>> It would even make sense to allow initial and default only if args has
>> length 1. This would again exclude cases where the arguments contain a
>> statically known redundancy, but this time the preconditions would be
>> more complicated.
> As I understand it, anyway, default really makes sense only when args has length 1 and args[0] is an iterable.
> Cannot really see the sense of initial for min()/max().

So the motivating case for a default argument boils down to:

* The input is an iterable (otherwise the number of positional arguments is already known when the call is written).
* The input is not a sequence of known length (otherwise, you could just use "min(seq) if seq else default").
* The input is potentially long (otherwise you could trivially convert to a sequence with list(iterable)).
* The input is potentially empty (otherwise you wouldn't need a default).
* There is a semantically meaningful default case for an empty input.
* You only want the min or max but no other information from the iterable (otherwise you would need to convert it to a sequence so 
that min/max wouldn't consume all the data).

I think this is a YAGNI case.  Yes, it does come up every now and then
but I don't think it is worth complicating what should be a very simple function.

FWIW, we recently rejected a perfectly reasonable addition to operator.attrgetter()
and operator.itemgetter() that would have added a default value.  The problem
is that it didn't work well with the other extensions that had already been accepted
(like having multiple arguments such as itemgetter(1, 4, 7) or dotted attribute
chains like attrgetter("store.department.register")).  The concept behind the rejection
is that it isn't worthwhile to overload a function with too many alternative extensions
even if the extensions make sense taken individually.

I contend that min/max are already in that position.   They already have some
signature complexity with min()-->TypeError; min(x)-->where-x-is-iterable;
min(x,y,z)-->where-args-are-unrolled; and min(*args) changing behavior based
on the length of args.  On top of that, we've already extended min/max with a
key= argument, further adding to its complexity.

I think the default arg is a bridge too far.  This is evidenced by the
complexity of the suggested implementations (remember the zen of python).
And, it is evidenced above discussion on signature complexity resulting from
a kitchen-sink full of individually simple extensions.  This is also evidenced
by the disagreements in this thread about what the various corner cases
should do.  And, at least one respondent significantly misinterpreted
the default-argument as being equivalent to a initial-argument.

There has been almost zero discussion on use cases.  There is no doubt
that they exist, but no compelling cases have been presented (i.e. real-world
code that is much improved with the extension).   Likewise, there has been
no discussion of alternatives (it is not hard to write an itertool that wraps
an iterator with something that supplies a default when the iterator is empty).

one-aspect-of-language-design-is-knowing-when-quit-ly yours,


More information about the Python-ideas mailing list