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?"