Python:分钟(无,x)
Posted
技术标签:
【中文标题】Python:分钟(无,x)【英文标题】:Python: min(None, x) 【发布时间】:2011-09-09 10:30:50 【问题描述】:我想执行以下操作:
a=max(a,3)
b=min(b,3)
但有时a
和b
可能是None
。
我很高兴地发现在max
的情况下效果很好,给出了我需要的结果3
,但是如果b
是None
,b
仍然是None
...
任何人都可以想到一个优雅的小技巧,让min
返回数字,以防万一没有参数之一?
【问题讨论】:
它没有做正确的事情。它恰好在两种情况之一中给出了您期望的结果,因为NoneType
和int
之间的无意义比较返回一个固定值,而不管整数值如何。在 Python 3 中,当您执行类似操作(比较没有有意义的排序的类型)时,您会得到一个 TypeError
。
似乎是 Python 中的一个不一致之处,最重要的是。
***.com/questions/2214194/…
如果您可以将 None 替换为默认的 int 值(如 0),您可以执行以下操作:max(a,3,key=lambda x: x or 0)
【参考方案1】:
为什么不创建一个没有 None 值的生成器?它更简单、更干净。
>>> l=[None ,3]
>>> min(i for i in l if i is not None)
3
【讨论】:
不需要列表理解。仍然 +1(提前 - 认真,请删除括号),这是一个干净简单的解决方案。 谢谢,没有大括号,Python 会像生成器表达式一样解释它吗? 是的。如果genexpr 是函数调用的唯一参数,则生成器表达式周围的括号是可选的。 这样的解决方案的一个潜在问题是它适用于列出的示例,但如果您有一个带有[None, None]
的列表,min()
函数将失败,因为您没有给出它一个有效的论点。
@KevinLondon,根据您想要的行为将 min 的默认值指定为 0 或 None。 min((x for x in [None,None] if x is not None), default=None)
【参考方案2】:
我对 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)
【讨论】:
【参考方案3】: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 是一个空序列
这段代码完全解决了这个问题
优点:
-
如果没有按顺序出现,则工作
使用 Python 3
max() 也可以使用
缺点
-
列表中需要多个非零变量。即 [0,None] 失败。
需要一个变量(例如lst)或需要复制序列
【讨论】:
这也适用于 Python 2.7。由于它还解决了其他解决方案的 min(None) 问题,它得到了我的 +1 一个不能处理的边界情况是lst
可能只包含 0 和 None 值。您希望它返回 0,但它会返回 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】: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)
【讨论】:
请注意,这仅在默认值为 0 时有效。传递 0 而不是None
仍会触发传递默认值,但不会更改值,因为默认值为 0(和 0 == 0.0 == 0j
)。
OP 说 max 不是问题。如果 b 为负数会怎样?【参考方案6】:
您可以使用内联 if
和 infinity 作为默认值,因为这适用于任何值:
a = max(a if a is not None else float('-inf'), 3)
b = min(b if b is not None else float('inf'), 3)
【讨论】:
好的,那我就说得更清楚一点 那么这有时会通过True
;)【参考方案7】:
a=max(a,3) if a is not None else 3
b=min(b,3) if b is not None else 3
【讨论】:
我总是尽量避免否定。所以我更喜欢b = 3 if b is None else min(b, 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
因此,这个 sn-p 可以防止错误:
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]))
【讨论】:
这会过滤掉零。以上是关于Python:分钟(无,x)的主要内容,如果未能解决你的问题,请参考以下文章