【发布时间】:2011-12-20 14:30:57
【问题描述】:
由于某种原因,tuple > list 形式的 Python 2.7 表达式返回 True,但 tuple < list 和 tuple == list 返回 False。这是为什么呢?
这个观察无论如何都不是我的原创。
【问题讨论】:
标签: python
由于某种原因,tuple > list 形式的 Python 2.7 表达式返回 True,但 tuple < list 和 tuple == list 返回 False。这是为什么呢?
这个观察无论如何都不是我的原创。
【问题讨论】:
标签: python
tuple 和 list 不是同一类型。当比较不同类型的值并且没有定义跨这些类型工作的比较器时,Python 做了一些令人惊讶的事情。它比较类名称的字典顺序:
>>> class Coffee(object):
... pass
...
>>> class Tea(object):
... pass
...
>>> c = Coffee()
>>> t = Tea()
>>> c > t
False
>>> c == t
False
>>> c < t
True
>>>
谢天谢地,在 python 3 中,这种情况消失了,比较这些类型会引发异常。
【讨论】:
tuple 和 list 不是同一类型。"错了,它们都是type类型。
list 和tuple 这两种类型有 相同的类型,type(list) is type(tuple) 但它们不是同一类型,type(list) is type and type(tuple) is type and list is not tuple
tuple 和 list 显然是不同的类型,但这对于这个问题完全无关紧要。 OP 询问了 list < tuple 等的奇怪结果,但您的回答一直在谈论比较不同类型的值,即使在示例代码中也是如此。这绝对不是你的语法不清楚的问题——我的意思是这个答案没有抓住重点(尽管只是稍微)。您解释了不同类型的值按其类型名称的字典顺序排序——这与比较 list 和 tuple 有什么关系?
list 或tuple 的值。
来自the doc:
运算符
<、>、==、>=、<=和!=比较两个对象的值。对象不必具有相同的类型。如果两者都是数字,则将它们转换为通用类型。否则,不同类型的对象总是比较不相等,并且顺序一致但随意。
【讨论】:
因为不同类型的python对象是任意比较的(至少在python 2.7中任意表示“按其类型名称按字母顺序排列”)。因此,tuple 将始终是 >,然后是 list。
The Python (2.7) Language Reference - 5.9. Comparisons:
大多数其他内置类型的对象比较不相等,除非它们是 同一个对象;一个对象是否被认为更小的选择 或大于另一个是任意但始终在 一个程序的一次执行。
比较不同类型的对象的规则不应该是 依靠;它们可能会在该语言的未来版本中发生变化。
This is the c function for comparing python objects(来自Python 2.7 source):
default_3way_compare(PyObject *v, PyObject *w)
{
int c;
const char *vname, *wname;
if (v->ob_type == w->ob_type) {
/* When comparing these pointers, they must be cast to
* integer types (i.e. Py_uintptr_t, our spelling of C9X's
* uintptr_t). ANSI specifies that pointer compares other
* than == and != to non-related structures are undefined.
*/
Py_uintptr_t vv = (Py_uintptr_t)v;
Py_uintptr_t ww = (Py_uintptr_t)w;
return (vv < ww) ? -1 : (vv > ww) ? 1 : 0;
}
/* None is smaller than anything */
if (v == Py_None)
return -1;
if (w == Py_None)
return 1;
/* different type: compare type names; numbers are smaller */
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);
if (c < 0)
return -1;
if (c > 0)
return 1;
/* Same type name, or (more likely) incomparable numeric types */
return ((Py_uintptr_t)(v->ob_type) < (
Py_uintptr_t)(w->ob_type)) ? -1 : 1;
}
要查看的主要部分是行(接近末尾):
else
wname = w->ob_type->tp_name;
c = strcmp(vname, wname);
【讨论】:
任意实现选择。这是 Python 3 中的 TypeError。
【讨论】: