This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Use of None in min and max
Type: enhancement Stage: resolved
Components: Versions: Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Brian.Mearns, r.david.murray, simeon.visser, steven.daprano
Priority: normal Keywords:

Created on 2014-12-02 14:25 by Brian.Mearns, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (5)
msg231998 - (view) Author: Maytag Metalark (Brian.Mearns) Date: 2014-12-02 14:25
`None` should never be the result of the built-in `min` and `max` functions. When `None` is supplied as one of the values to check, it should never be chosen as the result.

This would make it much easier to find a minimum and/or maximum while iterating over values. For instance, the following is a common pattern:

    mn = None
    mx = None
    for x in iterable:
        if mn is None or x < mn:
            mn = x
        if mx is None or x > mx:
            mx = x

Note that although the `min` and `max` functions could be applied directly to `iterable` in the above case, the above pattern is more efficient (only once through the loop) and covers the common case where additional operations are performed on each value of the iterable.

If the suggested enhancement was made, the above code could be written more simply as:

    mn = None
    mx = None
    for x in iterable:
        mn = min(mn, x)
        mx = max(mx, x)

At present, this will actually work for `max`, as None evaluates as less than every number, but it will not work for `min` (for the same reason).

The suggested change would mean that None is simultaneously greater than and less than every other value, but that only matters if we assume a total ordering of all the values including None, which doesn't seem like it would be important.
msg232005 - (view) Author: Simeon Visser (simeon.visser) Date: 2014-12-02 15:23
This doesn't happen in Python 3 as None can't be compared to other elements:

>>> min([1,2,3,None])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: NoneType() < int()

I can also imagine people now using min with the intended behaviour of "give me the smallest element, or None if it happens to be present".
msg232007 - (view) Author: Simeon Visser (simeon.visser) Date: 2014-12-02 15:44
So, to clarify, as the problem no longer occurs in Python 3 (as it requires the caller to provide only orderable objects) I'm not sure a meaningful change can be made here. It would require changing the behaviour of min/max in Python 2.7.x in a way that could break existing code.
msg232011 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2014-12-02 16:09
Just select your initial value as something that works with the sequence you are iterating.  If necessary, you can define custom 'always maximum' and 'always minimum' objects.  (You could try proposing builtin objects with that feature on the python-ideas mailing list, if you want to pursue this, but since this is a specialized need and usually you don't even need custom objects, I suspect you won't get much enthusiasm.  But I could be wrong, especially if you can some up with additional use cases.
msg232593 - (view) Author: Steven D'Aprano (steven.daprano) * (Python committer) Date: 2014-12-13 04:06
Even though I agree with closing this issue, there is some support for ignoring certain "missing values" when calculating min() and max(). The draft 2008 revision of IEEE-754 includes two functions maxNum and minNum which silently skip over NANs:

https://en.wikipedia.org/wiki/IEEE_754_revision#min_and_max

The R language also supports max and min skipping over missing values:

https://stat.ethz.ch/R-manual/R-devel/library/base/html/Extremes.html

The problem is that there are so many different things which somebody might want to do, it is hard to tell which (if any) the built-ins should support:

- silently skip over None
- or NANs
- or treat some other, user-specified, value as "missing"
- treat None as the smallest (or largest) value
- treat the presence of None as an error
- etc.

I think that min() and max() should continue to be relatively simple-minded and let users write their own more complex versions if needed, e.g. by calling min(filter(condition, values)).
History
Date User Action Args
2022-04-11 14:58:10adminsetgithub: 67168
2014-12-13 04:06:37steven.dapranosetnosy: + steven.daprano
messages: + msg232593
2014-12-02 16:09:39r.david.murraysetstatus: open -> closed

nosy: + r.david.murray
messages: + msg232011

resolution: not a bug
stage: resolved
2014-12-02 15:44:04simeon.vissersetmessages: + msg232007
2014-12-02 15:23:32simeon.vissersetnosy: + simeon.visser
messages: + msg232005
2014-12-02 14:25:38Brian.Mearnscreate