Minmax function alongside min and max

There’s something of a parallel with the built-in function divmod here. There’s an excellent reason for having divmod available, namely that it’s common to want to compute both a // b and a % b as part of some algorithm, and computing them separately is needlessly inefficient: in current CPython, a // b (for a and b of type int) computes both the quotient and the remainder, then throws the remainder away and returns the quotient. Similarly for a % b. So by evaluating a // b and a % b separately you’re computing the quotient and the remainder twice each instead of once. divmod solves this inefficiency.

Nevertheless, I’ve always found divmod oddly unsatisfying in practice, and despite writing a lot of integer-based algorithmic code, I almost never use divmod, and I rarely see it used in other people’s code. Part of the issue is readability: if I have an expression that uses both a % b and a // b and I want to use divmod for efficiency, I have to introduce a separate statement to call divmod(a, b) and unpack the resulting tuple. I can’t simply use divmod directly in my expression without using it twice, which defeats the point. So my functional-style code becomes more procedural and a mite harder to read as a result, especially since a function call is being substituted for operators.

I don’t know if we have, or can get, statistics on usage of builtins, but I’d hazard a guess that divmod is one of the least-used built-in functions. (To be clear, before anyone gets excited, I am not proposing that divmod be deprecated, moved, or removed. It is what it is.)

I suspect minmax would suffer from some of the same issues, though we don’t have the operator versus function call aspect. I think it wouldn’t get used as much as one might a priori expect. It might be useful to look at some before-and-after examples from real-world code to see to what extent readability is affected.

That’s not to say that minmax wouldn’t be useful, but in spite of min and max being builtins, I doubt that minmax would be useful often enough to justify adding it to builtins. Which leaves us with the issue of figuring out where it does belong, and I don’t have a good answer to that. math, statistics and itertools seem like the obvious candidates. Of the three, I’d probably go with math: it bothers me a bit that minmax, like min and max, wouldn’t necessarily be specifically for numbers, which makes math seem inappropriate, but we already have a precedent for putting a generic not-necessarily-numeric function in math, in the form of math.prod.

4 Likes