Skip to content Skip to sidebar Skip to footer

Difference Between 'any' With Generator-comprehension And Comprehension Without Parentheses?

Reviewing some of my code and I realized I had written what is essentially:' if (any(predicate for predicate in list_of_predicates)): # do something I had expected this syntax

Solution 1:

These expressions are equivalent. The performance difference is noise.

From the original genexp PEP:

if a function call has a single positional argument, it can be a generator expression without extra parentheses, but in all other cases you have to parenthesize it.

And viewing the disassembly, you can see that they compile to the same bytecode:

>>> deff():
... any(Truefor x in xrange(10))
...
>>> defg():
... any((Truefor x in xrange(10)))
...
>>> dis.dis(f)
  20 LOAD_GLOBAL              0 (any)
              3 LOAD_CONST               1 (<code object <genexpr> at 0000000002
B46A30, file "<stdin>", line 2>)
              6 MAKE_FUNCTION            09 LOAD_GLOBAL              1 (xrange)
             12 LOAD_CONST               2 (10)
             15 CALL_FUNCTION            118 GET_ITER
             19 CALL_FUNCTION            122 CALL_FUNCTION            125 POP_TOP
             26 LOAD_CONST               0 (None)
             29 RETURN_VALUE
>>> dis.dis(g)
  20 LOAD_GLOBAL              0 (any)
              3 LOAD_CONST               1 (<code object <genexpr> at 0000000002
BE0DB0, file "<stdin>", line 2>)
              6 MAKE_FUNCTION            09 LOAD_GLOBAL              1 (xrange)
             12 LOAD_CONST               2 (10)
             15 CALL_FUNCTION            118 GET_ITER
             19 CALL_FUNCTION            122 CALL_FUNCTION            125 POP_TOP
             26 LOAD_CONST               0 (None)
             29 RETURN_VALUE
>>> f.__code__.co_consts
(None, <code object <genexpr> at 0000000002B46A30, file "<stdin>", line 2>, 10)
>>> dis.dis(f.__code__.co_consts[1])  # the genexp's code object in f20 LOAD_FAST                0 (.0)
        >>    3 FOR_ITER                11 (to 17)
              6 STORE_FAST               1 (x)
              9 LOAD_GLOBAL              0 (True)
             12 YIELD_VALUE
             13 POP_TOP
             14 JUMP_ABSOLUTE            3
        >>   17 LOAD_CONST               0 (None)
             20 RETURN_VALUE
>>> dis.dis(g.__code__.co_consts[1])  # the genexp's code object in g20 LOAD_FAST                0 (.0)
        >>    3 FOR_ITER                11 (to 17)
              6 STORE_FAST               1 (x)
              9 LOAD_GLOBAL              0 (True)
             12 YIELD_VALUE
             13 POP_TOP
             14 JUMP_ABSOLUTE            3
        >>   17 LOAD_CONST               0 (None)
             20 RETURN_VALUE

Post a Comment for "Difference Between 'any' With Generator-comprehension And Comprehension Without Parentheses?"