Simon Forman wrote: ... > I usually use this with assert statements when I need to check a > sequence. Rather than: > > for something in something_else: assert expression > > I say > > assert False not in (expression for something in something_else) > > This way the whole assert statement will be removed if you use the '-O' > switch to the python interpreter. (It just occurred to me that that's > just an assumption on my part. I don't know for sure that the > interpreter isn't smart enough to remove the first form as well. I > should check that. ;P )
FWIW I did just check that and it seems valid, the second form gets "optimized" away. File delme.py: import dis N = (True, True, False) def a(): for n in N: assert n def b(): assert False not in (n for n in N) dis.dis(a) print '===============================' dis.dis(b) Results of running it without '-O': $ python delme.py 8 0 SETUP_LOOP 28 (to 31) 3 LOAD_GLOBAL 0 (N) 6 GET_ITER >> 7 FOR_ITER 20 (to 30) 10 STORE_FAST 0 (n) 9 13 LOAD_FAST 0 (n) 16 JUMP_IF_TRUE 7 (to 26) 19 POP_TOP 20 LOAD_GLOBAL 2 (AssertionError) 23 RAISE_VARARGS 1 >> 26 POP_TOP 27 JUMP_ABSOLUTE 7 >> 30 POP_BLOCK >> 31 LOAD_CONST 0 (None) 34 RETURN_VALUE =============================== 13 0 LOAD_GLOBAL 0 (False) 3 LOAD_CONST 1 (<code object <generator expression> at 0xb7d89ca0, file "delme.py", line 13>) 6 MAKE_FUNCTION 0 9 LOAD_GLOBAL 1 (N) 12 GET_ITER 13 CALL_FUNCTION 1 16 COMPARE_OP 7 (not in) 19 JUMP_IF_TRUE 7 (to 29) 22 POP_TOP 23 LOAD_GLOBAL 2 (AssertionError) 26 RAISE_VARARGS 1 >> 29 POP_TOP 30 LOAD_CONST 0 (None) 33 RETURN_VALUE Results of running it with '-O': $ python -O delme.py 8 0 SETUP_LOOP 14 (to 17) 3 LOAD_GLOBAL 0 (N) 6 GET_ITER >> 7 FOR_ITER 6 (to 16) 10 STORE_FAST 0 (n) 9 13 JUMP_ABSOLUTE 7 >> 16 POP_BLOCK >> 17 LOAD_CONST 0 (None) 20 RETURN_VALUE =============================== 13 0 LOAD_CONST 0 (None) 3 RETURN_VALUE -- http://mail.python.org/mailman/listinfo/python-list