Loop until condition is true

Magnus Lycka lycka at carmen.se
Wed Jun 22 10:16:29 EDT 2005


Remi Villatel wrote:
> Erm... You totally missed the point. I wrote it this way because, first, 
> it's perfectly valid Python code and, second and most important, it's 
> also a valid english sentence.

Remi, I think you have failed to understand what Fredrik was
telling you. I can understand that, because he didn't actually
explain the problem. He probably thought it was obvious, but
it seems it wasn't.

"if a is b:" is equivalent to "if id(a) == id(b)". It doesn't
test whether two values are the equal, it tests whether a and b
are the same object. None is a singleton object in Python, but
True is not. (At least not in the Python versions I use.)

That means that you are relying on Python to use a performance
optimization (interning of some common values, in this case
the integer 1, which is what True is in practice).

In some cases, "==" and "is" happens to give the same result.
 >>> a = 1
 >>> b = 1
 >>> a == b
1
 >>> a is b
1

But often not.

 >>> c = 123456789
 >>> d = 123456789
 >>> c == d
1
 >>> c is d
0

Or, for an example of the opposite:

 >>> class Smaller:
...     def __cmp__(self, other):
...             return -1
...
 >>> s = Smaller()
 >>> b = a
 >>> a < b
1
 >>> b < a
1
 >>> a == b
0
 >>> a is b
1

In other words, a test like "if x is None:" makes sense,
since None is a singleton, but "if x is True:" certainly
seems like buggy code that just happens to work. You could
write "if x == True:" without risking a failure in some
Python implementation that doesn't intern True (i.e. 1)
if you are certain that x is 0 or 1, but it's completely
redundant. Why stop there? Why not write
"if x == True == True:" or "if x == True == True == True:"?
These are all logically equivalent. You could also write
"if x and True:", or "if x or not True" :)

I understand what your intentions are: You feel that your
code is easier to understand written the way you did it, but
it stops feeling like that once you have gotten fully into
your head that the expressions (a) and (a == True) are
logically equivalent if a is either True or False.

If you manage to get away from this "x == True" mind-set
you are likely to write better Python code.

First of all, a lot of Python values except 1 (a.k.a. True)
are logically true in a Python expression. It's considered
good form to exploit that. E.g.

if y: z = x / y
if text: print text
if l: cols = len(l[0])

In these cases, adding a "==True", would break the code, and
adding more "correct" comparisions would just clutter the code,
which hides the intent and raises the risk for bugs, and make
it more difficult to keep the code as flexible as Python code
can be. E.g. if you change the last statement to
"if l != []: cols = len(l[0])", you'll get in trouble if it
turns out that l = (). The uncluttered code will still work.

Secondly, if you ever write logical expressions that are more
complex, you will make them much more difficult to read unless
you drop that "== True" baggage.

I'm convinced that it's easier to understand

    if past_six or past_three and saturday or sunday:

than to understand

    if (past_six==True or
        past_three==True and saturday==True or
        sunday==True):

I'm also pretty sure it's easier to write the first without
making any mistake.



More information about the Python-list mailing list