python 元组理解

1. python 元组比较语义 怪怪

1.1. Example

   1 
   2 ()<(1)
   3 (1)<(2)
   4 ()<(1,2)
   5 """result"""
   6 False
   7 True
   8 True

1.2. 怪怪

1 对于空tuple (),

  • cmp( (), (a)),

    如果 a 是含有一个原子元素的tuple, 结果为1,即 () > (a) 为真, 如果 a 是一个list, 结果也为真, 如果 a 是一个tuple,若含有的元素多于一个,结果为假,

    • 如仅含有一个原子元素,结果为真, 如果含有一个tuple元素, 递归 ##

对于含有更多元素的tuple间比较,嗷嗷,好像很复杂!

没看Python文档, 不清楚如何定义的.

看看源码? 好像对自己没什么用处尼?

1.3. 讨论

一个元素的元组不是(a),而应该是(a,)。如果只是(a)那只是一个括号运算。

>>> a=(1)
>>> a
1
>>> a=(1,)
>>> a
(1,)
  • -- Limodou

"()"是元组

>>> type(())
<type 'tuple'>
>>> 

元祖的比较: 先按长度比较,长度相同是再按内容比较. (我也没看参考, 猜测应该是这样)

  • -- Hoxide

是按tuple中每个元素进行比较的,不是先比较长度的,如:

(2,) > (1,2)
True

与长度无关。

  • -- Limodou

static PyObject *
tuplerichcompare(PyObject *v, PyObject *w, int op)
{
        PyTupleObject *vt, *wt;
        int i;
        int vlen, wlen;

        if (!PyTuple_Check(v) || !PyTuple_Check(w)) {
                Py_INCREF(Py_NotImplemented);
                return Py_NotImplemented;
        }

        vt = (PyTupleObject *)v;
        wt = (PyTupleObject *)w;

        vlen = vt->ob_size;
        wlen = wt->ob_size;

        /* Note:  the corresponding code for lists has an "early out" test
         * here when op is EQ or NE and the lengths differ.  That pays there,
         * but Tim was unable to find any real code where EQ/NE tuple
         * compares don't have the same length, so testing for it here would
         * have cost without benefit.
         */

        /* Search for the first index where items are different.
         * Note that because tuples are immutable, it's safe to reuse
         * vlen and wlen across the comparison calls.
         */
        for (i = 0; i < vlen && i < wlen; i++) {
                int k = PyObject_RichCompareBool(vt->ob_item[i],
                                                 wt->ob_item[i], Py_EQ);
                if (k < 0)
                        return NULL;
                if (!k)
                        break;
        }

        if (i >= vlen || i >= wlen) {
                /* No more items to compare -- compare sizes */
                int cmp;
                PyObject *res;
                switch (op) {
                case Py_LT: cmp = vlen <  wlen; break;
                case Py_LE: cmp = vlen <= wlen; break;
                case Py_EQ: cmp = vlen == wlen; break;
                case Py_NE: cmp = vlen != wlen; break;
                case Py_GT: cmp = vlen >  wlen; break;
                case Py_GE: cmp = vlen >= wlen; break;
                default: return NULL; /* cannot happen */
                }
                if (cmp)
                        res = Py_True;
                else
                        res = Py_False;
                Py_INCREF(res);
                return res;
        }

        /* We have an item that differs -- shortcuts for EQ/NE */
        if (op == Py_EQ) {
                Py_INCREF(Py_False);
                return Py_False;
        }
        if (op == Py_NE) {
                Py_INCREF(Py_True);
                return Py_True;
        }

        /* Compare the final item again using the proper operator */
        return PyObject_RichCompare(vt->ob_item[i], wt->ob_item[i], op);
}

这回看了源代码, 没什么好多说的了, truple的比较就是这样, 不过关于比较, python做得非常复杂, object.c里面有详细的代码, 可以做个专题仔细讲一下.

  • -- Hoxide

谢谢!看了源码的注释!有一点点明白了。先比较元素,再比较长度?

不要比较不同长度的tuple!

   1 
   2 >>>(4,5,6,7)>(3,4,5,5,8)  # 4>3? 
   3 True
   4 >>>(-2,3)>(1)             # -2>1? 
   5 True
   6 >>>(-2)>(1)              # -2<1 
   7 False