Moberg
Moberg

Reputation: 5503

Why isn't there any special method for __max__ in python?

As the title asks. Python has a lot of special methods, __add__, __len__, __contains__ et c. Why is there no __max__ method that is called when doing max? Example code:

class A:
    def __max__():
        return 5

a = A()
max(a)

It seems like range() and other constructs could benefit from this. Am I missing some other effective way to do max?¨

Addendum 1: As a trivial example, max(range(1000000000)) takes a long time to run.

Upvotes: 2

Views: 965

Answers (2)

Sraw
Sraw

Reputation: 20214

Some operations are not basic operations. Take max as an example, it is actually an operation based on comparison. In other words, when you get a max value, you are actually getting a biggest value.

So in this case, why should we implement a specified max function but not override the behave of comparison?


Think in another direction, what does max really mean? For example, when we execute max(list), what are we doing?

I think we are actually checking list's elements, and the max operation is not related to list itself at all.

list is just a container which is unnecessary in max operation. It is list or set or something else, it doesn't matter. What really useful is the elements inside this container.

So if we define a __max__ action for list, we are actually doing another totally different operation. We are asking a container to give us advice about max value.

I think in this case, as it is a totally different operation, it should be a method of container instead of overriding built-in function's behave.

Upvotes: 1

MSeifert
MSeifert

Reputation: 152647

I have no authoritative answer but I can offer my thoughts on the subject.

There are several built-in functions that have no corresponding special method. For example:

  • max
  • min
  • sum
  • all
  • any

One thing they have in common is that they are reduce-like: They iterate over an iterable and "reduce" it to one value. The point here is that these are more of a building block.

For example you often wrap the iterable in a generator (or another comprehension, or transformation like map or filter) before applying them:

sum(abs(val) for val in iterable)       # sum of absolutes
any(val > 10 for val in iterable)       # is one value over 10
max(person.age for person in iterable)  # the oldest person

That means most of the time it wouldn't even call the __max__ of the iterable but try to access it on the generator (which isn't implemented and cannot be implemented).

So there is simply not much of a benefit if these were implemented. And in the few cases when it makes sense to implement them it would be more obvious if you create a custom method (or property) because it highlights that it's a "shortcut" or that it's different from the "normal result".

For example these functions (min, etc.) have O(n) run-time, so if you can do better (for example if you have a sorted list you could access the max in O(1)) it might make sense to document that explicitly.

Upvotes: 3

Related Questions