I was wondering if the following two "if" statements compile down to the same bytecode for a standard Dictionary type:
m = {"foo": 1, "blah": 2}
if "foo" in m: print "sweet"
if m.has_key("foo"): print "dude"
To answer the question you actually asked, you can use dis.dis:
py> def f1(s, m): ... if s in m: ... pass ... py> def f2(s, m): ... if m.has_key(s): ... pass ... py> import dis py> dis.dis(f1) 2 0 LOAD_FAST 0 (s) 3 LOAD_FAST 1 (m) 6 COMPARE_OP 6 (in) 9 JUMP_IF_FALSE 4 (to 16) 12 POP_TOP
3 13 JUMP_FORWARD 1 (to 17) >> 16 POP_TOP >> 17 LOAD_CONST 0 (None) 20 RETURN_VALUE py> dis.dis(f2) 2 0 LOAD_FAST 1 (m) 3 LOAD_ATTR 1 (has_key) 6 LOAD_FAST 0 (s) 9 CALL_FUNCTION 1 12 JUMP_IF_FALSE 4 (to 19) 15 POP_TOP
3 16 JUMP_FORWARD 1 (to 20) >> 19 POP_TOP >> 20 LOAD_CONST 0 (None) 23 RETURN_VALUE
Note that in the *bytecode*, f1 uses COMPARE_OP, while f2 uses LOAD_ATTR and CALL_FUNCTION. So no, the bytecode is different.
If the question you meant to as was "Do Python's builtin dicts use the same code for 'in' and 'has_key'?", you can check dictobject.c:
static PyMethodDef mapp_methods[] = { {"__contains__",(PyCFunction)dict_has_key, METH_O | METH_COEXIST, contains__doc__}, ... {"has_key", (PyCFunction)dict_has_key, METH_O, has_key__doc__}, ... };
Note that both __contains__ and has_key are mapped to dict_has_key. So yes, the same C code will be executed in both cases[1].
STeVe
[1] modulo the different lookup paths to find these methods -- http://mail.python.org/mailman/listinfo/python-list