【问题标题】:What are built-in Python 3 types that can be compared to each other?可以相互比较的内置 Python 3 类型有哪些?
【发布时间】:2019-09-05 18:41:27
【问题描述】:

在 Python 2 中,可以通过隐式比较类型的文本字符串(即按字典顺序,字符串 'int' 小于比字符串'str' 和字符串'list' 小于字符串'tuple')。

因此,在 Python 2 中,5 < 'hello' 返回 True。可以阅读更多关于为什么在回答 Why is ''>0 True in Python? 时允许这样做。

在 Python 3 中,这会引发 builtins.TypeError: unorderable types: int() < str() 异常。

这个web page

Python 3 中严格的比较方法使其通常 无法比较不同类型的对象。

这是否意味着有一些内置类型或特殊情况可以比较任何内置类型而不会导致TypeError?我不是在谈论自定义类型,其中实现了必要的 dunder 方法以正确支持比较。

【问题讨论】:

  • 当然,您可以先将intfloat 进行比较。您也可以将它们与bool 进行比较。您还可以将setfrozenset 进行比较。
  • Python 2 的行为不仅仅是对类型名称进行字符串比较。例如,5 < ArithmeticError() 即使'int' > 'ArithmeticError'

标签: python python-3.x comparison operators typing


【解决方案1】:

所有这些都是有效的陈述(并且它们都评估为True):

0 < True
0 < 1.
0. < True
{0} < frozenset((0, 1))

这里唯一可能看起来很奇怪的是0. == False1. == True

另一方面,您仍然可以通过在比较之前将您的值转换为 str 来重现 python 2 所做的事情(这也评估为 True):

str(5) < 'hello'

如果你真的需要这种行为,你总是可以有一个可以转换/比较的函数。这样你就可以保证不同类型的对象总是以相同的方式进行比较,这似乎是 python 2 中唯一的约束。

def lt(a, b):
    return str(a) < str(b)

或者甚至更好,你可以只在需要时施放:

def lt(a, b):
  try: 
    return a < b
  except TypeError: 
    return str(a) < str(b)

另一方面,正如 cmets 中所建议的,在 CPython 的实现中,似乎是通过以下方式进行比较:

def lt(a, b):
  try: 
    return a < b
  except TypeError: 
    if a is None:
      return True
    if b is None: 
      return False
    if isinstance(a, numbers.Number):
      return True
    if isinstance(b, numbers.Number):
      return False
    return str(type(a)) < str(type(b))

【讨论】:

  • 好的,这很有用。 intbool 的比较在这里讨论 stackoverflow.com/questions/2764017/…
  • boolint 的子类,因此您可以将bools 与其他数字进行比较并不奇怪。
  • Python 2 的行为不等同于str(5) &lt; 'hello'。 Python 2 的行为是一堆奇怪的、依赖于实现的怪癖,但对于 CPython 上 5 &lt; 'hello' 的特定情况,5 被认为更小,因为它是一个数字,而 'hello' 不是。
  • 您可能误解了问题断言值是通过 type 名称进行比较的部分,而不是通过对值进行字符串化。类型名称比较是奇怪的怪癖的一部分,尽管不是全部。
  • 在你的代码中,5'4' 大,这与实际 CPython 2 中的 5 &lt; '4' 不同。
【解决方案2】:

我之前已经在网上查过了,除了上面提到的少数特殊情况外,它们似乎在 Python 3 中确实无法排序。

这种变化通常体现在排序列表中:在 Python 3 中,具有不同类型项目的列表通常是不可排序的。 如果您需要对异构列表进行排序,或比较不同类型的对象,请实现一个关键函数来完整描述不同类型应如何排序。
Source

我不知道为什么,但有些人找到了使用 Python 3 重现 Python 2 行为的方法。

也许你应该看看thisthatThis question 也强调了 2011 年的变化:

找到它:埋在 PEP 3100 中:“不同类型之间除 == 和 != 之外的比较将引发异常,除非该类型明确支持”

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 2013-02-24
    • 2020-09-11
    • 2018-03-12
    相关资源
    最近更新 更多