[Python-ideas] "Exposing" `__min__` and `__max__`

Franklin? Lee leewangzhong+python at gmail.com
Wed Jun 27 11:16:06 EDT 2018

On Wed, Jun 27, 2018, 10:31 Steven D'Aprano <steve at pearwood.info> wrote:

> 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?

Let's just assume Michael wants to know, and isn't making an argument
against the proposal.

`range` is more a sequence (a collection) than a generator. It's not Python
2's xrange. You can iterate through one multiple times. If `range` did not
have a length, we would eventually propose that it should.

I can't think of a real iterable which has no length but knows what its max
is. An iterator or generator can't generally know its max without consuming
everything. I have some vague thoughts about collections which have known
bounds but not known sizes, but nothing concrete.

It's bikeshedding, anyway. How isn't as important as whether it's useful.

By the way, range(1e7) fails with a type error.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180627/fb36e168/attachment-0001.html>

More information about the Python-ideas mailing list