How is the __contains__ method of the list class in Python implemented?

前端 未结 3 862
感动是毒
感动是毒 2020-12-19 12:30

Suppose I define the following variables:

mode = \"access\"
allowed_modes = [\"access\", \"read\", \"write\"]

I currently have a type check

3条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-19 12:46

    Not equivalent since the any requires an extra function call, a generator expression and things.

    >>> mode = "access"
    >>> allowed_modes =["access", "read", "write"]
    >>> 
    >>> def f1():
    ...    mode in allowed_modes
    ... 
    >>> def f2():
    ...    any(mode == x for x in allowed_modes)
    ... 
    >>> 
    >>> 
    >>> import dis
    >>> dis.dis
    dis.dis(          dis.disassemble(  dis.disco(        dis.distb(        
    >>> dis.dis(f1)
      2           0 LOAD_GLOBAL              0 (mode)
                  3 LOAD_GLOBAL              1 (allowed_modes)
                  6 COMPARE_OP               6 (in)
                  9 POP_TOP
                 10 LOAD_CONST               0 (None)
                 13 RETURN_VALUE
    >>> dis.dis(f2)
      2           0 LOAD_GLOBAL              0 (any)
                  3 LOAD_CONST               1 ( at 0x7fb24a957540, file "", line 2>)
                  6 LOAD_CONST               2 ('f2..')
                  9 MAKE_FUNCTION            0
                 12 LOAD_GLOBAL              1 (allowed_modes)
                 15 GET_ITER
                 16 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
                 19 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
                 22 POP_TOP
                 23 LOAD_CONST               0 (None)
                 26 RETURN_VALUE
    >>> 
    

    This is more instructive than the python source for the methods themselves but here is the source of __contains__ for lists and the loop is in C which will probably be faster than a Python loop.

    Some timing numbers confirm this.

    >>> import timeit
    >>> timeit.timeit(f1)
    0.18974408798385412
    >>> timeit.timeit(f2)
    0.7702703149989247
    >>> 
    

提交回复
热议问题