Lotte Lotte - 6 months ago 8
Python Question

Alternate syntax for "while True" loop?

I'm still relatively new to Python and have been using statements like the following:

flag = False
while flag == False:
# Do something here that might set the flag to True,
flag = True


However this could be written like so:

while not flag:
# Do something...
flag = True
while flag is False:
# Do something...
flag = True


With a further (preferred?) way of writing this type of loop:

while True:
# Do something and if wanting wanting to break out of loop,
break


The first three methods are more explicit, so why are they (or one of them) not preferred over the fourth method? Are there any differences between the first three ways of writing the "while flag == False"?

Answer

All of them are technically different.

Example 1

Say you have a function call that doesn't return anything meaningful, as follows:

def fun(x=None):
    return x

Now, for your while loops, all of which will be defined as follows:

def while1():
   flag = False
   while flag == False:
      flag = fun(None)

def while2():
   flag = False
   while flag is False:
      flag = fun(None)

def while3():
   flag = False
   while not flag:
      flag = fun(None)

In this case, only while1 and while2 will terminate. Since bool(None) evaluates to False, while3 will continue infinitely, but since None != False and None is not False, both while1 and while2 will terminate.

Now, this gets more interesting with more complicated examples.

Example 2

def fun(x):
    return x

Now, for each of our loops, we're going to change flag = fun() to flag = fun(0).

In this case, while1 and while3 terminate, while while2 continues indefinitely. This is because bool(0) == False, and 0 == False, but 0 is not False.

Example 3 -- Mutables

Now, this gets a lot more complicated with mutables, which is why the explicit versus implicit depends situation to situation. Mutables are any object that can be modified, and include dicts, lists. Immutable objects are anything that cannot be modified, such as tuples, ints, floats, strs.

Say I have the following:

a = []
b = []

In this case, bool(a) == False, and a == b, but a is not b. In short, there is no, simple, steadfast rule for how to check falsey or truthey values.

However, there are general rules.

General Rules

Checking None vs. Other If you accept any value other than None, check x is None.

Checking mutables Never use x is b, since mutables can have different IDs, unless if you explicitly want to check to an object with the same ID (id(x) == id(b). Typically, check not x or x == b

>>> a = []
>>> b = []
>>> a is b
False
>>> a == b
True
>>> not a
True

Checking strs, floats and integers For strs, floats and ints, always check x == b and not x is b. This is since for short strings, floats, ints, the results can be true if x == b, but for more complicated cases, your code will stop working.

For example:

>>> a = 1
>>> a is 1
True
>>> a = 10000000
>>> a is 10000000
False

Checking booleans

For booleans, you can do any of the above, but not x is preferable to x == b or x is b.

Finally... While Loops

If you can, always convert a while loop to a for loop. This isn't always possible, but say you want to do a simple case:

x = 0
while x < 10:
    print(x)
    x -= 1

This can be converted to:

for x in range(10):
    print(x)

The reason for using for loops rather than while loops is if some error occurs in your code, while loops can lead to an indefinite loop and crash your program, while a for loop will always exit.

Comments