[Python-ideas] Have max and min functions ignore None
Franklin? Lee
leewangzhong+python at gmail.com
Tue Dec 29 01:49:43 EST 2015
I was hoping that my message was clear enough that I wouldn't get
suggestions of alternatives. I know how to do without it.
Take this example:
from collections import defaultdict
from math import inf
def maxes(lst):
bests = defaultdict(lambda: -inf)
for x, y in lst:
bests[x] = max(bests[x], y)
return bests
The proposed change would only save me an import, and I could've used
`inf = float('inf')` instead.
from collections import defaultdict
def maxes(lst):
bests = defaultdict(lambda: None)
for x, y in lst:
bests[x] = max(bests[x], y)
return bests
On Mon, Dec 28, 2015 at 11:52 PM, Terry Reedy <tjreedy at udel.edu> wrote:
> On 12/28/2015 11:08 PM, Franklin? Lee wrote:
>>
>> What do people think about having `max` and `min` ignore `None`?
>>
>> Examples:
>> max(1, None) == 1
>> min(1, None) == 1
>
>
> This amounts to saying that the comparisions 1 < None and 1 > None are both
> defined and both True.
Not exactly.
max(1, None) == max(None, 1) == 1
There is no definable comparison to None which allows both max and min
to return the correct value.
> rewrite this as
>
> def my_best(iterable):
> it = iter(iterable)
> try:
> best = it.next()
> except StopIteration:
> raise ValueError('Empty iterable has no maximum')
> for x in it:
> if x > best:
> best = x
Well, `my_best = max` is the cleanest way. It's not the point.
>> Currently, you would initialize `best` to the first element,
>
>
> Since an empty iterable has no max (unless one wants to define the
> equivalent of float('-inf') as a default), initializing with the first
> element is the proper thing to do.
Mathematically, the max of the empty set is the min of the ambient
set. So the max of an empty collection of natural numbers is 0, while
the max of an empty collection of reals is -inf. Of course, Python
doesn't know what type of elements your collection is expected to
have, so (as Nick said) you would manually specify the default with a
keyword argument. But that's not the point.
>> I'm concerned about this silencing some bugs which would have been
>> caught before. I'm also worried about whether it would make sense to
>> people learning Python.
>
>
> None currently means 'no value', which means that most operations on None
> are senseless.
No value, like a lack of something to consider in the calculation of
the maximum?
PS: This change would also allow one to use a `key` function which
returns None for an object that shouldn't be considered. Now _that_
might be more useful. But again, I know how to deal without it: have
the key function return `inf` or `-inf` instead. I'm asking if using
`None` could become the "one obvious way to do it". There is semantic
meaning to initializing `best = None`, after all: "At this point,
there is no best yet."
More information about the Python-ideas
mailing list