【问题标题】:Python: Usable Max and Min valuesPython:可用的最大值和最小值
【发布时间】:2012-05-14 01:16:08
【问题描述】:

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

一个有用的快捷方式(此处为 Python 2.7)是 None 比较小于任何整数或浮点值:

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

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

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

当您可能对整数和浮点数的混合列表进行排序并希望有一个绝对最小值和最大值可供参考时,此快捷方式很有用。

此快捷方式已在 Python 3000 中被删除(这是 Python 3.2):

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

此外,Python3000 has removed sys.maxint 的理论是所有整数都提升为长整数并且限制不再适用。

PEP 326,顶部和底部值的案例,在 Python 中高级参考最小值和最大值。新的排序行为documented

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

编辑

有几个答案是“只使用 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 

还有:

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

还是:

>>> () > 2**5000
True

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

结论

感谢大家的回答和cmets。我选择了 TryPyPy 的 answer,因为它似乎最符合我的要求:维基百科中描述的绝对最大和绝对最小值 entry on infinity.

通过这个问题,我了解到long或int值不会转换为float才能完成float('inf') &gt; 2**5000的比较。我不知道。

【问题讨论】:

  • float("inf") 有什么问题,或者,如果您需要号码,sys.float_info.max
  • IIRC 异质值按其类型名称的字母顺序排列 - 几乎没有用处
  • “Python3000 已经删除了 sys.maxint,因为理论上所有的 int 都提升为 long,并且限制不再适用。”,不,Python3000 已经删除了 intperiod。现在所有整数都是long,这就是它被重命名的原因。
  • "为了将 cmp 转换为浮点值,float('inf'),需要将 long 值转换为浮点数。"不,这不是 float 到 long(或 float 到 int)比较的工作方式。 (它不能那样工作,从那时起你将失去平等的传递性,对 dict 和 set 包含产生各种可怕的后果。)将 float('inf') 与 10**1000 进行比较不应引发 OverflowError。
  • @carrot-top 正如 Pyson 所说,你目前对 float('inf') 的观点并不好。现在,Mark Dickinson 是 CPython 核心和库中所有数字的当前维护者。如果他也说 float('inf') 还可以,我就不会费心寻找更多反例了。

标签: python python-3.x


【解决方案1】:

对于数值比较,+- float("inf") 应该可以工作。

它并不总是有效(但涵盖了实际情况):

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.

要让对象与任何其他任意对象(包括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>]

当然,覆盖“或等于”变体需要更多努力。它不会解决无法对包含Nones 和ints 的列表进行排序的一般问题,但是通过一点包装和/或 decorate-sort-undecorate 魔法(例如,对列表进行排序)也应该可以解决这个问题(typename, value) 的元组)。

【讨论】:

  • FWIW,当你在一个容器中突然有许多 MIN(或等效的作弊者)时,这种作弊就会中断,如果它是自动排序的,那就更糟了。
【解决方案2】:

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

另外,请注意,在 Py2 中,None 小于一切,而空元组大于一切都保证,例如,Jython 和 PyPy 完全有权使用如果他们愿意,可以选择不同的顺序。所保证的只是解释器的一个运行副本内的一致性——实际顺序是任意的。

【讨论】:

  • 您甚至可以将无穷大的浮点形式分配给MAXMIN,然后继续前进。
  • 3&gt;&gt; float('-inf') &lt; (3+4j) Traceback (most recent call last): File "&lt;stdin&gt;", line 1, in &lt;module&gt; TypeError: unorderable types: float() &lt; complex()
  • @IgnacioVazquez-Abrams:不太公平,因为任何仅包含复数的列表也是不可排序的(以及任何一对复数):)
  • 正如在别处提到的,float('nan') 的排序高于float('inf')(因为 > 和
  • @TryPyPy 仅适用于“已解决”的有限定义。这种损坏是由容器中的 NaN 开始排序引起的,而不是 float(inf) 不是数字类型的“真实”最大值。 NaN 可以在“排序”容器中随处可见,甚至不会一起浮动,这就是例证。所有自定义 MAX/MIN 保证它们不会是第一个或最后一个;当然,这取决于用例,但似乎只过滤掉 NaN 通常会更好。
【解决方案3】:

在 cPython 中,cmp 不执行隐式转换为浮点数。即,这有效:

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

虽然这显式执行了可怕的转换:

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

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

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...

如果你想要一个值,那么float('-inf') for min 和float('inf') 是相当安全的。但是,请务必将其缓存在循环之外:

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

【讨论】:

  • &gt;&gt;&gt; cmp(1.0**4999,10.0**5000)
  • cmp() 在 Py3 中也消失了。
  • ** 操作在这里为您提供了OverflowErrors。与比较无关。
  • 哪个更快?与 inf 比较或在每个循环中检查 x 是否为 None?
猜你喜欢
  • 1970-01-01
  • 2019-01-09
  • 2015-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-02
  • 2023-04-02
相关资源
最近更新 更多