Python中不是None的最小数字

时间:2014-01-27 02:49:01

标签: python minimum

这个问题接近我的问题,但不完全是:List minimum in Python with None?。我需要考虑列表中所有值都是None的可能性。

我有一种情况,我必须在数据库中查找一些数字,它们可能存在或返回为null。我需要找到现有数字的最小值。例如:

min_if_exists(1, 2) returns 1
min_if_exists(5, None) returns 5
min_if_exists(None, None) returns None

幸运的是我可以这样做:

def min_if_exists(a, b):
    return min(a, b)
elif a:
    return a
elif b:
    return b
else:
    return None

以下是上述问题的答案:

lowest = min(x for x in (a, b) if x is not None)

但是,如果a和b为None,我会得到一个例外,因为我输入了一个空序列。我可以简单地捕获异常,或者我可以在序列中包含任意大的数字(a,b,100000000)。对于一个任意长的数字序列,可能都是None,我可以(大概)以非Python的方式做到这一点:

def min_if_exists(list_of_nums):
    not_a_none_exists = False
    for n in list_of_nums:
        if n is not None:
            not_a_none_exists = True
    if not_a_none_exists:
        return min(x for x in list_of_nums if x is not None)
    else:
        return None

有更多的Pythonic,更简洁的方法吗?

3 个答案:

答案 0 :(得分:7)

试试这个,这是一个pythonic解决方案:

def min_if_exists(list_of_nums):
    try:
        return min(x for x in list_of_nums if x is not None)
    except ValueError:
        return None

请记住:在Python中,请求宽恕比获得更容易!引用documentation

  

这种常见的Python编码风格假设存在有效的键或属性,并且如果假设被证明是错误则捕获异常。这种干净和快速的风格的特点是存在许多try和except语句。该技术与许多其他语言(如C)共有的LBYL(在你跳跃前看)风格形成鲜明对比。

答案 1 :(得分:2)

如果您等待Python 3.4,则可以非常干净地执行此操作,因为minmax会增加默认参数(请参阅问题#18111):

>>> def min_not_none(seq):
...     return min((x for x in seq if x is not None), default=None)
... 
>>> print(min_not_none([3,None,1]))
1
>>> print(min_not_none([None]))
None

答案 2 :(得分:1)

我认为Oscar Lopez的基于异常处理的答案是一个非常好的选择。这是另一种选择(可能是次要的):

def my_min(lst):
    if lst == [None]*len(lst):
        return None
    else:
        return min(x for x in lst if x is not None)

print(my_min([0,2,-1]))           # -1
print(my_min([0,2,None]))         # 0
print(my_min([None, None, None])) # None