Python: min (None, x)

Я хотел бы выполнить следующее:

a=max(a,3)
b=min(b,3)

Однако иногда a и b могут быть None.
Я был рад узнать, что в случае max он работает хорошо, давая мой требуемый результат 3, однако если b есть None, b остается None...

Кто-нибудь может подумать об изящном маленьком трюке, чтобы min вернуть число в случае одного из аргументов в None?

Ответы

Ответ 1

Почему бы вам просто не создать генератор без значений None? Это проще и чище.

>>> l=[None ,3]
>>> min(i for i in l if i is not None)
3

Ответ 2

Решение для Python 3

Код:

# переменная lst - ваша последовательность

min(filter(lambda x: x is not None, lst)) if any(lst) else None

Примеры:

In [3]: lst = [None, 1, None]

In [4]: min(filter(lambda x: x is not None, lst)) if any(lst) else None
Out[4]: 1

In [5]: lst = [-4, None, 11]

In [6]: min(filter(lambda x: x is not None, lst)) if any(lst) else None
Out[6]: -4

In [7]: lst = [0, 7, -79]

In [8]: min(filter(lambda x: x is not None, lst)) if any(lst) else None
Out[8]: -79

In [9]: lst = [None, None, None]

In [10]: min(filter(lambda x: x is not None, lst)) if any(lst) else None

In [11]: print(min(filter(lambda x: x is not None, lst)) if any(lst) else None)
None

Примечание:

Работает в последовательности представлены как числа, а не None. Если все значения отсутствуют, min() вызывает исключение

ValueError: min() arg - пустая последовательность

Этот код решает эту проблему вообще

Плюсы:

  1. Сработало, если Ни один не представлен в последовательности
  2. Работал на Python 3
  3. max() также будет работать

Против

  1. Нужно более одной ненулевой переменной в списке. то есть [0, None] не удается.
  2. Нужна переменная (пример lst) или нужно дублировать последовательность

Ответ 3

def max_none(a, b):
    if a is None:
        a = float('-inf')
    if b is None:
        b = float('-inf')
    return max(a, b)

def min_none(a, b):
    if a is None:
        a = float('inf')
    if b is None:
        b = float('inf')
    return min(a, b)

max_none(None, 3)
max_none(3, None)
min_none(None, 3)
min_none(3, None)

Ответ 4

Вот встроенный декоратор, который вы можете использовать для фильтрации значений None, которые могут быть переданы функции:

noNones = lambda fn : lambda *args : fn(a for a in args if a is not None)
print noNones(min)(None, 3)
print noNones(max)(None, 3)

печатает:

3
3

Ответ 5

Вы можете использовать встроенную if и бесконечность по умолчанию, так как это будет работать для любого значения:

a = max(a if a is not None else float('-inf'), 3)
b = min(b if b is not None else float('inf'), 3)

Ответ 6

Мое решение для Python 3 (3.4 и выше):

min((x for x in lst if x is not None), default=None)
max((x for x in lst if x is not None), default=None)

Ответ 7

a=max(a,3) if a is not None else 3
b=min(b,3) if b is not None else 3

Ответ 8

Ответ на @utdemir отлично подходит для приведенного примера, но может вызвать ошибку в некоторых сценариях.

Одна проблема возникает, если у вас есть список только с значениями None. Если вы предоставите пустую последовательность min(), она вызовет ошибку:

>>> mylist = [None, None]
>>> min(value for value in mylist if value)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: min() arg is an empty sequence

Таким образом, этот фрагмент предотвратит ошибку:

def find_minimum(minimums):
    potential_mins = (value for value in minimums if value is not None)
    if potential_mins:
        return min(potential_mins)

Ответ 9

Я считаю, что самый простой способ - использовать встроенную функцию фильтра

a = max(filter(None, [a, 3]))
b = min(filter(None, [b, 3]))