[Python-ideas] "Exposing" `__min__` and `__max__`
Steven D'Aprano
steve at pearwood.info
Wed Jun 27 10:27:01 EDT 2018
On Wed, Jun 27, 2018 at 06:52:14AM -0700, Michael Selik wrote:
> > > Have you ever written ``max(range(x))`` in production code?
> >
> > I have never written that.
> >
> > But I have written ``max(iterable)`` dozens of times, where iterable
> > could be a range object.
> >
>
> My intent was to ask where a range was in fact passed into max, not merely
> where it could be. It'd be enlightening to see a complete, realistic
> example.
A complete, realistic example is as I said: you call max() on some
object which you don't control, the caller does. You could be
passed a list, or a set, or a bitset, a binary search tree, a range
object, whatever the caller happens to pass to you.
If you control your own input, then this doesn't sound too interesting.
You know when you will get a list, and you can call max() on it, and you
know when you are passing yourself a tree, and you can give your own
tree a max() method and call that.
But if you don't control your input, then this is a good way to delegate
back to the unknown object of an unknown class which knows itself.
Currently max() and min() have no choice but to walk the entire data
structure, even if the object already knows its own maximum and minimum
values. That's wasteful.
An analogy: in Ruby, the equivalent of the len() built-in falls back on
iteration as a last resort for any object which doesn't define a len
method:
size = 0
for x in obj:
size += 1
return size
By this analogy, max() and min() currently are like that last-resort
version of len(), except they do it for *every* object that can be
iterated over even when there's no need.
Imagine that Python's len() always walked the entire iterable, from
start to end, to count the length. Now suppose that you proposed
adding a __len__ protocol so that objects that know their own length
can report it quickly, and in response I argued that
len(range(x))
was unrealistic and that there is no need for a __len__ method
because we could just say
range(x).stop
instead. I don't think you would find that argument very persuasive,
would you?
--
Steve
More information about the Python-ideas
mailing list