On Mon, 23 Jan 2012 20:50:11 +0000, Andrea Crotti wrote: > while 1 works because the 1 is converted to boolean automatically, but > why not just writing a boolean > in the first place?
You have misunderstood Python's truth model. It is similar to languages like Javascript and PHP, where EVERY object without exception has a truth value. Python does not convert 1 to a boolean, because that would be pointless and silly. Bools True and False in Python are no more privileged than anything else, in fact they are *less* privileged in Python 2 because they are merely built-in names which can be re-bound, not reserved words like None. In Python 2, the peephole optimizer can optimize away constants such as 1. But 1 itself is not special -- any non-zero int, or non-empty string, is also a true-ish value: >>> from dis import dis >>> dis(compile('if 42: spam', '', 'exec')) 1 0 LOAD_NAME 0 (spam) 3 POP_TOP 4 LOAD_CONST 0 (None) 7 RETURN_VALUE While True is just a name, and therefore needs to be looked up at runtime like every other name: >>> dis(compile('if True: spam', '', 'exec')) 1 0 LOAD_NAME 0 (True) 3 JUMP_IF_FALSE 8 (to 14) 6 POP_TOP 7 LOAD_NAME 1 (spam) 10 POP_TOP 11 JUMP_FORWARD 1 (to 15) >> 14 POP_TOP >> 15 LOAD_CONST 0 (None) 18 RETURN_VALUE In Python 3, True and False become constants, like None, and the peephole optimizer can treat them like 42 or 0 or -3. Nevertheless, the important factor is not the optimizer, but the JUMP_IF_FALSE op-code. That accepts *any* Python object, not just True and False: >>> dis(compile('if [1, 2, 3]: spam', '', 'exec')) 1 0 LOAD_CONST 0 (1) 3 LOAD_CONST 1 (2) 6 LOAD_CONST 2 (3) 9 BUILD_LIST 3 12 JUMP_IF_FALSE 8 (to 23) 15 POP_TOP 16 LOAD_NAME 0 (spam) 19 POP_TOP 20 JUMP_FORWARD 1 (to 24) >> 23 POP_TOP >> 24 LOAD_CONST 3 (None) 27 RETURN_VALUE Note that a sufficiently clever peephole optimizer could have recognised that [1,2,3] is a true value, just as 42 is a true value. But that's besides the point: what is important is that any object is true-ish or false-ish. The only advantages to True and False are: (1) They satisfy programmers from Pascal and other languages which insist on actual Boolean types in comparisons. You can recognise these people who haven't quite yet grasped Python's model, and are still writing Pascal or Java, because they write unpythonic code which does unnecessary work, such as "if bool(x)" instead of just "if x". Worse are the ones who write "if bool(x) is True", because they don't even understand boolean logic. (2) They are self-documenting, especially for return values. If a function returns 0 or 1, there may be some uncertainty whether that should be understood as a number, or a flag. By returning False or True, it self-documents that it is a flag. (3) It avoids people having to define their own true/false values, with a multitude of spellings, in every library and project that uses them. If your branch (while loop or if/elif clause) is taking a constant literal, you probably should prefer True/False over any other object simply because it is more readable and clear as to your intention. But it is no big deal if you prefer 1/0 instead. If you branch over an arbitrary named object, like "while x", there is no point in writing that as "while bool(x)". All that does is indicate that you are uncomfortable with, or don't understand, Python's truth model, and perform an extra, unnecessary, name lookup and function call. -- Steven -- http://mail.python.org/mailman/listinfo/python-list