Search code examples
pythonmaxminassignment-operator

Min or Max assignment operator in Python


Given:

variableX = 5
someValueY = 6

Imagine you want to assign to variableX the maximum of variableX and someValueY:

variableX = max(variableX, someValueY)

I more than once figured it would be nice to have something like:

variableX max= someValueY

Comparable to += and the other assignment operators.

Is this a good idea, does it already exist and isn't this Pythonic?


Solution

  • Per the language reference, "augmented assignment":

    is the combination, in a single statement, of a binary operation and an assignment statement

    (emphasis mine). max isn't a binary operation (it takes an arbitrary number of positional arguments plus the key keyword argument), so your proposed operator would not be consistent with the existing suite. You would presumably also want min=, but what about the other built-in functions?


    At an implementation level, note that this proposal would mean adding a whole layer of complexity to the parsing of Python code; either there is some exception to parsing if the name happens to be max (or min, or whatever else you want to provide for) or any name would be treated the same way, i.e.:

    foo func= bar
    

    would just be syntactic sugar for:

    foo = func(foo, bar)
    

    (or func(bar, foo); what if the function isn't commutative?)


    In the comments, you mention x max= y, z would become x = max(x, y, z), so either the second argument is a tuple that gets unpacked, e.g.:

    foo func= bar
    

    would be translated to:

    foo = func(foo, *bar)
    

    (which means that a trailing comma is required for a single value: x max= y,), or we are implementing yet more new syntax.


    This is a lot of effort in implementation, testing and maintenance (not to mention another thing for beginners to learn before they can read Python code). Adding new syntax to a language must always have a very strong case and, per the Zen of Python (import this):

    There should be one-- and preferably only one --obvious way to do it.

    That "one obvious way" is the existing syntax, foo = func(foo, bar). This doesn't apply to the existing suite as, per the relevant PEP

    The idea behind augmented assignment in Python is that it isn't just an easier way to write the common practice of storing the result of a binary operation in its left-hand operand, but also a way for the left-hand operand in question to know that it should operate `on itself', rather than creating a modified copy of itself.

    For this to apply to max=, we would now have to allow objects to implement e.g. __imax__ (c.f. __iadd__ for +=), which would imply also having a regular __max__ method, and potentially leads on to arbitrary __func__ and __ifunc__ methods, which is yet another can of worms. The more I think about this, the worse an idea it seems...


    Within a class, you can implement this with a descriptor to set maximum and minimum values for specific attributes; see e.g. Implementing a decorator to limit setters.