36

Is there any clever in-built function or something that will return 1 for the min() example below? (I bet there is a solid reason for it not to return anything, but in my particular case I need it to disregard None values really bad!)

>>> max([None, 1,2])
2
>>> min([None, 1,2])
>>> 
TrebledJ
  • 8,713
  • 7
  • 26
  • 48
c00kiemonster
  • 22,241
  • 34
  • 95
  • 133

3 Answers3

54

None is being returned

>>> print min([None, 1,2])
None
>>> None < 1
True

If you want to return 1 you have to filter the None away:

>>> L = [None, 1, 2]
>>> min(x for x in L if x is not None)
1
nosklo
  • 217,122
  • 57
  • 293
  • 297
  • 35
    Note that `None` is only returned in Python 2. In Python 3, `min([None, 1, 2])` yields a `TypeError: '<' not supported between instances of 'int' and 'NoneType'`. – Kurt Peek Sep 26 '17 at 11:10
9

using a generator expression:

>>> min(value for value in [None,1,2] if value is not None)
1

eventually, you may use filter:

>>> min(filter(lambda x: x is not None, [None,1,2]))
1
Adrien Plisson
  • 22,486
  • 6
  • 42
  • 73
  • 3
    The syntax has nothing python 3. It works in python 2 just fine. Using `is` for comparing with `None` as in `value is not None` is prefered to using `==` (or `!=`). The line with `filter` is **wrong**, try putting a 0 in the list and you'll see it will get filtered too, which is not what you want. – nosklo Feb 19 '10 at 10:23
  • Which is quicker, a list comprehension or a filter? – c00kiemonster Feb 19 '10 at 10:25
  • @c00kiemonster: They don't do the same thing. a `filter` is **wrong** here, as I pointed in my comment. – nosklo Feb 19 '10 at 10:26
  • oh i see, when you said filter in your reply, you meant filter through a list comprehension, and not filter as in filter()... – c00kiemonster Feb 19 '10 at 10:28
  • @nosklo: sorry, i thought generator expressions were introduced in python 3. i already corrected the `is not None`. and you are right the filter was wrong, corrected now... – Adrien Plisson Feb 19 '10 at 10:36
  • now after the edit, the `filter()` version got very very ugly... :P – nosklo Feb 19 '10 at 10:52
  • @nosklo: i even wrote a worse version: `import functools, operator; min(filter(partial(operator.is_not,None),[None,1,2]))`. with the problem you pointed earlier, there is now nothing to gain using `filter()`. python is missing a function for testing the common case of being None... – Adrien Plisson Feb 19 '10 at 11:13
  • @Adrien Plisson: Please FIX the first line of your answer; you don't use a list comprehension and as mentioned by nosklo "Python 3 syntax" is irrelevant. – John Machin Feb 19 '10 at 14:08
3

Make None infinite for min():

def noneIsInfinite(value):
    if value is None:
        return float("inf")
    else:
        return value

>>> print min([1,2,None], key=noneIsInfinite)
1

Note: this approach works for python 3 as well.

gregory
  • 10,969
  • 2
  • 30
  • 42