为什么一个空字典比1大?

15

为什么以下代码是正确的?

>>> foo = {}
>>> foo > 1
True
>>> foo < 1
False
>>> foo == 0
False
>>> foo == -1
False
>>> foo == 1
False

我知道我想要的是 len(foo) > 1,但作为一个初学者,这让我感到惊讶。


13
值得庆幸的是,在Python 3中这已经被禁止了。 - Tim Pietzcker
2
请注意,它不仅仅是大于1,而是大于所有整数。 - David Robinson
3
为了让意思更加清晰,任何序列总是大于任何数字。例如,foo > float('inf')的结果为True。对于列表、元组等序列以及字典也适用此规则。虽然这并没有解释其原理,但希望这能使事情变得更加明了。 - Joe Kington
@JoeKington 来源?我认为它是基于类型名称的,所以你描述的属性最多只能是巧合。另外,字典不是一个序列(它是一个映射)。 - user395760
5
这甚至让使用Python的人感到惊讶。这就是为什么它被移除的原因。 - user395760
显示剩余2条评论
3个回答

14
文档中得知: 运算符<, >, ==, >=, <=和!=会比较两个对象的值。这些对象不一定是相同类型的。如果两个对象都是数字,它们将被转换为公共类型。否则,不同类型的对象始终比较不相等,并且按照一致但是任意的顺序排序。您可以通过定义一个`__cmp__`方法或像`__gt__`这样的丰富比较方法来控制非内置类型的对象的比较行为(请参见第3.4节)。 (为了简化诸如排序和in和not in 操作之类的操作的定义,使用了这种不同寻常的比较定义。在未来,不同类型的对象的比较规则可能会发生变化。)

7

在Python 2.x中,不同类型之间的比较是基于类型名称进行的,但在Python 3.x中已被禁止。无论如何,在Python 2.x中,排序保证对于特定的Python实现和版本会给出相同的结果,但排序本身没有定义。


3
我也打算写那个,但是我想了想:“可是“int” > “dict”,所以为什么foo < 1呢?” - Tim Pietzcker
6
《5.3. Comparisons》(http://docs.python.org/2/library/stdtypes.html#comparisons)中提到:“CPython实现的细节:除数字外,不同类型的对象按其类型名称排序;不支持适当比较的相同类型的对象按其地址排序。” 因此,这通常是正确的,只是对于数字不适用。很奇怪。 - user395760

3
我认为这可能源于比较运算符只需要部分定义就可以派生出来的事实,即如果你可以测试 == 和 <,那么你可以派生其余的运算符,<= 是 (< 或 ==),> 不是 <=,等等。所以在 foo = {} 的情况下,您可以得到以下内容:

Python 2:

>>> foo == 0
False
>>> foo < 0
False
>>> not (foo <= 0)
True
so:
>>> foo > 0
True

python 3:

>>> foo = {}
>>> foo < 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: dict() < int()
>>> foo > 0
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: dict() > int()
>>> foo == 0
False
>>> 

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