Python2 - 在 None 类型上使用 min/max

Posted

技术标签:

【中文标题】Python2 - 在 None 类型上使用 min/max【英文标题】:Python2 - using min/max on None type 【发布时间】:2013-03-09 13:08:58 【问题描述】:

我注意到虽然 'max' 函数在 None 类型上表现良好:

In [1]: max(None, 1)
Out[1]: 1

'min' 函数不返回任何内容:

In [2]: min(None, 1)
In [3]: 

也许是因为没有 min(None, 1) 的定义? 那么为什么在最大情况下,它返回数字? None 是否被视为“-infinity”?

【问题讨论】:

请注意,这在 python3 中不起作用,其中 None 和标量之间的关系未定义。代码将引发 TypeError。 【参考方案1】:

正如 jamylak 所写,None 根本不会被 Python shell 打印出来。

这很方便,因为所有函数都有返回值:当没有指定值时,它们返回None

>>> def f():
...     print "Hello"
...     
>>> f()
Hello
>>> print f()  # f() returns None!
Hello
None

这就是 Python shell 不打印 returned None 值的原因。但print None 不同,因为它明确要求 Python 打印 None 值。


至于比较,None被认为是-infinity。

Python 2 的 general rule 是无法以任何有意义的方式比较的对象在比较时不会引发异常,而是返回一些任意结果。在 CPython 的情况下,任意规则如下:

除数字外的不同类型的对象按其类型排序 姓名;不支持正确比较的相同类型的对象 按地址排序。

对于像1 > None 这样的无意义比较以及通过max(1, None) 完成的比较,Python 3 会引发异常。


如果你确实需要 -infinity,Python 提供了float('-inf')

【讨论】:

那么,为什么 max(None,1) 返回 1 ?这是任意的? 请注意,此规则仅适用于 Python 2。在 Python 3 中,它已修复,您会收到一条有意义的错误消息 unorderable types: int() < NoneType()。 @mclafee 他们都返回了一个值,如果你阅读 EOLs 的解释就很清楚了 @mclafee: max(None, 1) 确实是未定义的。我引用的 CPython 2 的“按类型名称排序”规则似乎不适用于整数和 None 之间的比较,因为 None 的类型为 'NoneType',位于 'int' 之后。不过,也许第二条规则确实适用(在我做的测试中id(1) > id(None)True)。 @EOL:我不确定您是否在“id(1) > id(None)”中进行测试? id 返回对象 id。我试图测试 "type(1) > type(None)" 这是 False... @mclafee: id() 在 CPython 中返回对象的地址,这是 CPython 中比较某些对象的方式 (docs.python.org/2/library/functions.html#id)。【参考方案2】:

它确实返回了一些东西,python shell 只是不打印None

>>> min(None, 1)
>>> print min(None, 1)
None

【讨论】:

【参考方案3】:

如果你真的想要一个总是比其他值少的值,你需要创建一个小类:

class ValueLessThanAllOtherValues(object):
    def __cmp__(self, other):
        return -1

# really only need one of these
ValueLessThanAllOtherValues.instance = ValueLessThanAllOtherValues()

这个类将与任何其他类型的值进行比较:

tiny = ValueLessThanAllOtherValues.instance
for v in (-100,100,0,"xyzzy",None):
    print(v)
    print(v > tiny)
    print(tiny < v)
    # use builtins
    print(min(tiny,v))
    print(max(tiny,v))
    # does order matter?
    print(min(v,tiny))
    print(max(v,tiny))
    print()

打印:

-100
True
True
<__main__.ValueLessThanAllOtherValues object at 0x2247b10>
-100
<__main__.ValueLessThanAllOtherValues object at 0x2247b10>
-100

100
True
True
<__main__.ValueLessThanAllOtherValues object at 0x2247b10>
100
<__main__.ValueLessThanAllOtherValues object at 0x2247b10>
100

0
True
True
<__main__.ValueLessThanAllOtherValues object at 0x2247b10>
0
<__main__.ValueLessThanAllOtherValues object at 0x2247b10>
0

xyzzy
True
True
<__main__.ValueLessThanAllOtherValues object at 0x2247b10>
xyzzy
<__main__.ValueLessThanAllOtherValues object at 0x2247b10>
xyzzy

None
True
True
<__main__.ValueLessThanAllOtherValues object at 0x2247b10>
None
<__main__.ValueLessThanAllOtherValues object at 0x2247b10>
None

tiny 比它自己还小!

print(tiny < tiny)
True

【讨论】:

您的ValueLessThanAllOtherValues 比其他任何东西都小并不完全正确。例如,以相同方式定义的任何其他类在放在比较左侧时会产生更小的对象。原因是比较中的 first 对象的__cmp__() 首先被调用(因此您的__cmp__() 可能不会被调用)。 大跳蚤背上有小跳蚤咬他们,小跳蚤有小跳蚤,如此循环往复。 你不需要在 numpy 中这样做,这就是 np.NINF 的用途,至少对于数字而言。

以上是关于Python2 - 在 None 类型上使用 min/max的主要内容,如果未能解决你的问题,请参考以下文章

Python2.X学习摘录

在 Python 2.7 中检查字符串“None”或“not”

hdu1115多边形求重心模板

python2 学习 数据类型和变量

python2和3在处理字符串上的区别

如何让Ultraedit支持python语法高亮