从文档中:
对于Unipre和字符串类型,
x in y当且仅当 x 是 y 的子字符串时,才为true 。等效测试为y.find(x) !=-1。注意, x 和 y 不必是同一类型;因此,u'ab' in 'abc'将返回True。
空字符串始终被视为任何其他字符串的子字符串,因此"" in "abc"将返回True。
通过查看
要更深入,请看一下字节码:
>>> def answer():... '' in 'lolsome'>>> dis.dis(answer) 20 LOAD_ConST 1 ('') 3 LOAD_ConST 2 ('lolsome') 6 COMPARE_OP 6 (in) 9 POP_TOP 10 LOAD_ConST 0 (None) 13 RETURN_VALUE
COMPARE_OP是我们进行布尔运算并查看源代码以
in揭示比较发生位置的地方:
TARGET(COMPARE_OP) { w = POP(); v = TOP(); if (PyInt_CheckExact(w) && PyInt_CheckExact(v)) { register long a, b; register int res; a = PyInt_AS_LONG(v); b = PyInt_AS_LONG(w); switch (oparg) { case PyCmp_LT: res = a < b; break; case PyCmp_LE: res = a <= b; break; case PyCmp_EQ: res = a == b; break; case PyCmp_NE: res = a != b; break; case PyCmp_GT: res = a > b; break; case PyCmp_GE: res = a >= b; break; case PyCmp_IS: res = v == w; break; case PyCmp_IS_NOT: res = v != w; break; default: goto slow_compare; } x = res ? Py_True : Py_False; Py_INCREF(x); } else { slow_compare: x = cmp_outcome(oparg, v, w); } Py_DECREF(v); Py_DECREF(w); SET_TOP(x); if (x == NULL) break; PREDICT(POP_JUMP_IF_FALSE); PREDICT(POP_JUMP_IF_TRUE); DISPATCH(); }
并且cmp_outcome在同一文件中,很容易找到我们的下一个提示:
res = PySequence_Contains(w, v);
在abstract.c中:
{ Py_ssize_t result; if (PyType_HasFeature(seq->ob_type, Py_TPFLAGS_HAVE_SEQUENCE_IN)) { PySequenceMethods *sqm = seq->ob_type->tp_as_sequence; if (sqm != NULL && sqm->sq_contains != NULL) return (*sqm->sq_contains)(seq, ob); } result = _PySequence_IterSearch(seq, ob, PY_ITERSEARCH_CONTAINS); return Py_SAFE_DOWNCAST(result, Py_ssize_t, int);}
为了从源头上获得帮助,我们在文档中找到了下一个功能:
objobjproc PySequenceMethods.sq_contains此功能可能由
PySequence_Contains()相同的签名使用。该插槽可以保留为 NULL
,在这种情况下,PySequence_Contains()仅遍历序列,直到找到匹配项为止。
并在同一文档中进一步介绍:
int PySequence_Contains(PyObject *o, PyObject *value)确定 o是否 包含 值 。如果 o中 的项等于 value
,则返回1,否则返回0。出错时,返回-1。这等效于Python表达式value in o。
如果
''不是
null,则
'lolsome'可以认为该序列包含该序列。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)