Python:可用的最大值和最小值

时间:2021-08-24 18:22:19

Python 2.x allows heterogeneous types to be compared.

Python 2.x允许比较异构类型。

A useful shortcut (in Python 2.7 here) is that None compares smaller than any integer or float value:

一个有用的快捷方式(在Python 2.7中)是None比任何整数或浮点值都小:

>>> None < float('-inf') < -sys.maxint * 2l < -sys.maxint
True

And in Python 2.7 an empty tuple () is an infinite value:

在Python 2.7中,空元组()是一个无限值:

>>> () > float('inf') > sys.maxint
True

This shortcut is useful when one might sort a mixed list of ints and floats and want to have an absolute minimum and maximum to reference.

当人们可能对int和float的混合列表进行排序并希望具有绝对最小值和最大值时,此快捷方式非常有用。

This shortcut has been removed in Python 3000 however (this is Python 3.2):

这个快捷方式已经在Python 3000中删除了(这是Python 3.2):

>>> None < 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: NoneType() < int()

Furthermore, Python3000 has removed sys.maxint on the theory that all ints promote to longs and the limit no longer applies.

此外,Python3000已经删除了sys.maxint,理论上所有的int都提升为longs,并且限制不再适用。

PEP 326, A Case for Top and Bottom Values, advanced a reference min and max in Python. The new ordering behavior documented.

PEP 326,一个顶部和底部值的案例,在Python中提高了参考最小值和最大值。记录了新的排序行为。

Since PEP 326 was rejected, what are useful, useable definitions for a min and max value that work with integers and floats and longs on Python 2X and Python 3000?

由于PEP 326被拒绝,在Python 2X和Python 3000上使用整数和浮点数和长整数的最小值和最大值有用,可用的定义是什么?

Edit

Several answers are along the lines of "just use maxv=float('inf')"... The reason I am thinking, however remote the possibility, is this:

有几个答案是“只使用maxv = float('inf')”...我想的原因,无论多么遥远的可能性,是这样的:

>>> float(2**5000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: long int too large to convert to float 

And:

>>> cmp(1.0**4999,10.0**5000)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: (34, 'Result too large')

Yet:

>>> () > 2**5000
True

In order to cmp to a float value, float('inf'), the long value would need to be converted to a float and the conversion would cause an OverflowError...

为了cmp到浮点值float('inf'),需要将long值转换为float,转换会导致OverflowError ...

Conclusion

Thank you everyone for your answers and comments. I picked TryPyPy's answer because it seemed most inline with what I was asking: an absolute greatest and absolute least value as described in the Wikipedia entry on infinity.

谢谢大家的回答和评论。我选择了TryPyPy的答案,因为它似乎与我所要求的内容最为一致:绝对最大且绝对最小值,如*条目中关于无限的描述。

With this question, I learned that a long or int value is not converted to a float in order to complete the comparison of float('inf') > 2**5000. I did not know that.

有了这个问题,我了解到long或int值没有转换为float,以便完成float('inf')> 2 ** 5000的比较。我不知道。

3 个解决方案

#1


11  

For numerical comparisons, +- float("inf") should work.

对于数值比较,+ - float(“inf”)应该有效。

EDIT: It doesn't always work (but covers the realistic cases):

编辑:它并不总是有效(但涵盖了现实案例):

print(list(sorted([float("nan"), float("inf"), float("-inf"), float("nan"), float("nan")])))
# NaNs sort above and below +-Inf
# However, sorting a container with NaNs makes little sense, so not a real issue.

To have objects that compare as higher or lower to any other arbitrary objects (including inf, but excluding other cheaters like below), you can create classes that state their max/min-ness in their special methods for comparisons:

要使对象与任何其他任意对象(包括inf,但不包括下面的其他作弊者)相比更高或更低,您可以创建在其特殊方法中表示其最大/最小值的类以进行比较:

class _max:
    def __lt__(self, other): return False
    def __gt__(self, other): return True

class _min:
    def __lt__(self, other): return True
    def __gt__(self, other): return False

MAX, MIN = _max(), _min()

print(list(sorted([float("nan"), MAX, float('inf'), MIN, float('-inf'), 0,float("nan")])))
# [<__main__._min object at 0xb756298c>, nan, -inf, 0, inf, nan, <__main__._max object at 0xb756296c>]

Of course, it takes more effort to cover the 'or equal' variants. And it will not solve the general problem of being unable to sort a list containing Nones and ints, but that too should be possible with a little wrapping and/or decorate-sort-undecorate magic (e.g. sorting a list of tuples of (typename, value)).

当然,需要更多的努力来覆盖'或相同'的变体。并且它不能解决无法对包含Nones和int的列表进行排序的一般问题,但这也应该可以通过一些包装和/或decorate-sort-undecorate魔术来实现(例如,排序元组列表(typename,值))。

#2


10  

You have the most obvious choices in your question already: float('-inf') and float('inf').

你已经在你的问题中有了最明显的选择:float(' - inf')和float('inf')。

Also, note that None being less than everything and the empty tuple being higher than everything wasn't ever guaranteed in Py2, and, eg, Jython and PyPy are perfectly entitled to use a different ordering if they feel like it. All that is guaranteed is consistency within one running copy of the interpreter - the actual order is arbitrary.

另外,请注意,None小于一切,并且在Py2中无法保证空元组高于一切,例如,Jython和PyPy完全有权使用不同的顺序,如果他们感觉到的话。所有保证的是在一个正在运行的解释器副本中的一致性 - 实际的顺序是任意的。

#3


3  

In cPython, the cmp does not perform a conversion to float implicitly. i.e., this works:

在cPython中,cmp不会隐式执行浮动转换。即,这有效:

>>> float('inf') > 2**5000
True

While this explicitly performs the dread conversion:

虽然这明确执行了恐惧转换:

>>> float('inf') > float(2**5000)
Overflow...

The correct answer, IMHO, is not a value per se by a change in logic:

正确答案,恕我直言,逻辑上的变化本身并不是一个价值:

def func_with_min():
   minval=None
   for loop in list_with_mins:
      if minval is None or minval<minseen:
          # do that min thing you wanna do...

If you want to have a value then float('-inf') for min and float('inf') is pretty safe. Be sure to cache that outside of a loop however:

如果你想要一个值,那么float(' - inf')表示min和float('inf')非常安全。但请确保将其缓存在循环外部:

def func():
   minval=float('-inf')
   for loop in now_you_can_loop:
       # otherwise float('-inf') is kinda slow

#1


11  

For numerical comparisons, +- float("inf") should work.

对于数值比较,+ - float(“inf”)应该有效。

EDIT: It doesn't always work (but covers the realistic cases):

编辑:它并不总是有效(但涵盖了现实案例):

print(list(sorted([float("nan"), float("inf"), float("-inf"), float("nan"), float("nan")])))
# NaNs sort above and below +-Inf
# However, sorting a container with NaNs makes little sense, so not a real issue.

To have objects that compare as higher or lower to any other arbitrary objects (including inf, but excluding other cheaters like below), you can create classes that state their max/min-ness in their special methods for comparisons:

要使对象与任何其他任意对象(包括inf,但不包括下面的其他作弊者)相比更高或更低,您可以创建在其特殊方法中表示其最大/最小值的类以进行比较:

class _max:
    def __lt__(self, other): return False
    def __gt__(self, other): return True

class _min:
    def __lt__(self, other): return True
    def __gt__(self, other): return False

MAX, MIN = _max(), _min()

print(list(sorted([float("nan"), MAX, float('inf'), MIN, float('-inf'), 0,float("nan")])))
# [<__main__._min object at 0xb756298c>, nan, -inf, 0, inf, nan, <__main__._max object at 0xb756296c>]

Of course, it takes more effort to cover the 'or equal' variants. And it will not solve the general problem of being unable to sort a list containing Nones and ints, but that too should be possible with a little wrapping and/or decorate-sort-undecorate magic (e.g. sorting a list of tuples of (typename, value)).

当然,需要更多的努力来覆盖'或相同'的变体。并且它不能解决无法对包含Nones和int的列表进行排序的一般问题,但这也应该可以通过一些包装和/或decorate-sort-undecorate魔术来实现(例如,排序元组列表(typename,值))。

#2


10  

You have the most obvious choices in your question already: float('-inf') and float('inf').

你已经在你的问题中有了最明显的选择:float(' - inf')和float('inf')。

Also, note that None being less than everything and the empty tuple being higher than everything wasn't ever guaranteed in Py2, and, eg, Jython and PyPy are perfectly entitled to use a different ordering if they feel like it. All that is guaranteed is consistency within one running copy of the interpreter - the actual order is arbitrary.

另外,请注意,None小于一切,并且在Py2中无法保证空元组高于一切,例如,Jython和PyPy完全有权使用不同的顺序,如果他们感觉到的话。所有保证的是在一个正在运行的解释器副本中的一致性 - 实际的顺序是任意的。

#3


3  

In cPython, the cmp does not perform a conversion to float implicitly. i.e., this works:

在cPython中,cmp不会隐式执行浮动转换。即,这有效:

>>> float('inf') > 2**5000
True

While this explicitly performs the dread conversion:

虽然这明确执行了恐惧转换:

>>> float('inf') > float(2**5000)
Overflow...

The correct answer, IMHO, is not a value per se by a change in logic:

正确答案,恕我直言,逻辑上的变化本身并不是一个价值:

def func_with_min():
   minval=None
   for loop in list_with_mins:
      if minval is None or minval<minseen:
          # do that min thing you wanna do...

If you want to have a value then float('-inf') for min and float('inf') is pretty safe. Be sure to cache that outside of a loop however:

如果你想要一个值,那么float(' - inf')表示min和float('inf')非常安全。但请确保将其缓存在循环外部:

def func():
   minval=float('-inf')
   for loop in now_you_can_loop:
       # otherwise float('-inf') is kinda slow