为什么4 < '3'
会在Python 2中返回True
?
是不是因为当我在一个数字周围放置单引号时,Python认为它是一个字符串,字符串比数字大?
答案 0 :(得分:31)
是的,任何数字都将小于Python 2中的任何字符串(包括空字符串)。
在Python 3中,您无法进行任意比较。 You'll get a TypeError
.
来自the link in eryksun's comment:
if (PyNumber_Check(v))
vname = "";
else
vname = v->ob_type->tp_name;
if (PyNumber_Check(w))
wname = "";
else
wname = w->ob_type->tp_name;
c = strcmp(vname, wname);
因此,至少在CPython 2.x的最新版本中,比较类型名称,使用空字符串代替任何数字类型的类型名称。
答案 1 :(得分:7)
From Python v2.7.2 documentation
除数字外的不同类型的对象按其类型名称排序;不支持正确比较的相同类型的对象按其地址排序。
当您订购两个字符串或两个数字类型时,排序以预期的方式完成(字符串的字典顺序,整数的数字排序)。
订购字符串和整数时,会对类型名称进行排序。 “str”在“int”,“float”,“long”,“list”,“bool”等之后按字典顺序排列。但是元组将比字符串排序更高,因为“tuple”&gt; “str”:
0 > 'hi'
False
[1, 2] > 'hi'
False
(1, 2) > 'hi'
True
另见docs.python.org
中的comparison uses lexicographical ordering在Python 3.x中,行为已被更改,因此尝试对整数和字符串进行排序会引发错误:
>>> '10' > 5
Traceback (most recent call last):
File "", line 1, in
'10' > 5
TypeError: unorderable types: str() > int()
答案 2 :(得分:-1)
cpython 2中的默认比较操作基于相关对象的内存地址。来自python 2.7中的type_richcompare()
:
/* Compare addresses */
vv = (Py_uintptr_t)v;
ww = (Py_uintptr_t)w;
switch (op) {
case Py_LT: c = vv < ww; break;
case Py_LE: c = vv <= ww; break;
case Py_EQ: c = vv == ww; break;
case Py_NE: c = vv != ww; break;
case Py_GT: c = vv > ww; break;
case Py_GE: c = vv >= ww; break;
default:
result = Py_NotImplemented;
goto out;
}
result = c ? Py_True : Py_False;
这对于平等和不平等非常有效,但对于排序操作可能是违反直觉的,所以它已经针对Python 3进行了更改。事实上,当给出-3
时,2.7将针对此类用法发出警告标志。
要查看给定对象的内存地址,可以使用id()
内置函数。它只被定义为为每个单独的对象返回唯一的东西,但是cpython使用对象的内存地址作为方便的快捷方式。
小整数恰好比短字符串具有更小的内存地址,至少在某些python版本中,可能是由于cpython使用缓存来提高性能。