Python 2如何比较字符串和整数?为什么列表比数字更大,元组比列表更大?

182
以下代码段已用输出进行了注释(在ideone.com上看到):
print "100" < "2"      # True
print "5" > "9"        # False

print "100" < 2        # False
print 100 < "2"        # True

print 5 > "9"          # False
print "5" > 9          # True

print [] > float('inf') # True
print () > []          # True

有人能解释一下为什么输出是这样的吗?


实现细节

  • 这种行为是语言规范所要求的,还是由实现者决定的?
  • 主要的 Python 实现之间有差异吗?
  • Python 语言版本之间有差异吗?

26
在这个问题的3000个重复中,这个问题有一个回答解释了为什么语言是以这种方式设计的(以及为什么在3.x中重新设计)。这不是这个问题的一部分,但是是许多被链接到这里的问题的一部分。 - abarnert
请参考以下内容(非重复):https://dev59.com/OHE95IYBdhLWcg3wp_un - Karl Knechtel
2个回答

210

来自Python 2手册

CPython实现细节:除了数字之外的不同类型的对象按其类型名称排序;不支持适当比较的相同类型的对象按其地址排序。

当您对两个字符串或两种数字类型进行排序时,按预期方式进行排序(字符串按词典顺序排列,整数按数字大小排列)。

当您对一个数字和一个非数字类型进行排序时,数字类型位于前面。

>>> 5 < 'foo'
True
>>> 5 < (1, 2)
True
>>> 5 < {}
True
>>> 5 < [1, 2]
True

如果你比较两个不兼容的类型,且它们都不是数字类型,那么它们会按照类型名称的字母顺序排序:

>>> [1, 2] > 'foo'   # 'list' < 'str' 
False
>>> (1, 2) > 'foo'   # 'tuple' > 'str'
True

>>> class Foo(object): pass
>>> class Bar(object): pass
>>> Bar() < Foo()
True

有一个例外是旧式类总是位于新式类之前。

>>> class Foo: pass           # old-style
>>> class Bar(object): pass   # new-style
>>> Bar() < Foo()
False

这种行为是由语言规范指定的吗,还是由实现者自行决定?

Python没有明确的语言规范,但语言参考文档中说明:

否则,不同类型的对象总是比较不相等,并且按照一致但任意的顺序进行排序。

因此,这是一个实现细节。

在主要的 Python 实现之间是否存在差异?

我无法回答这个问题,因为我只使用过官方的 CPython 实现,但是还有其他的 Python 实现,例如 PyPy。

Python 语言的不同版本之间是否有差异?

在 Python 3.x 中,行为已更改,试图对整数和字符串进行排序将引发错误:

>>> '10' > 5
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    '10' > 5
TypeError: unorderable types: str() > int()

59
很好,他们在Py3k中进行了修改。当我第一次看到这个问题时,我的想法是“什么,这不会引发错误吗?” - JAL
9
特别说明,在Python 2.x 版本中,不同类型的对象按照类型名称进行排序,但是None对象始终比其他任何类型都小。在Python 3.x 中,将None与其他类型进行比较仍会引发TypeError异常。 - Dave Kirby
5
bool是一种数字类型。由于True等于1,因此它既不小于也不大于其他数字。 - abarnert
4
类型名称的字典顺序?你何时需要将其作为一个特性呢?谁会使用它? - Jacklynn
4
有趣的事实:complex(1,0) > 'abc'False,但complex(1,0) > complex(0,0)会引发TypeError错误。 - Eric Duminil
显示剩余5条评论

24

字符串 按字典序 进行比较,不同类型的数据则通过其类型名进行比较("int" < "string")。3.x版本通过使它们不可比较来解决第二个问题。


3
但在Python2中,整数类型的优先级低于字典类型,因此无法仅通过类型名称的字典序进行比较。 - Tony Suffolk 66
1
我刚看到这个答案,同意Tony Suffolk的观点。当对象不同时,它们不会按类型名称排序。 - Exelian
@TonySuffolk66 数字类型是这个规则的例外。在2.7中,NumericType始终低于任何其他类型(除了NoneType)。 - lef

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接