Why avoid while loops?

The general issue with while loops is that it is easy to overlook, or somehow skip the statement where the loop variable gets incremented. Even a C for-loop can have this problem - you can write for(int x=0; x<10;), although it is unlikely. But a Python for loop has no such problem, since it takes care of advancing the iterator for you. On the other hand, a while loop forces you to implement a never fail increment.

s = "ABCDEF"
i = 0
while (i < len(s)):
    if s[i] in "AEIOU":
        print s[i], 'is a vowel'
        # oops, this is one level too deep
        i += 1

is an infinite loop as soon as you hit the first non-vowel.


The advice seems poor to me. When you're iterating over some kind of collection, it is usually better to use one of Python's iteration tools, but that doesn't mean that while is always wrong. There are lots of cases where you're not iterating over any kind of collection.

For example:

def gcd(m, n):
    "Return the greatest common divisor of m and n."
    while n != 0:
        m, n = n, m % n
    return m

You could change this to:

def gcd(m, n):
    "Return the greatest common divisor of m and n."
    while True:
        if n == 0:
            return m
        m, n = n, m % n

but is that really an improvement? I think not.


Python follows the philosophy of

There should be one-- and preferably only one --obvious way to do it.

(see https://www.python.org/dev/peps/pep-0020/ for details).

And in most cases there is a better way to do iterations in Python than using a while loop.

Additionally at least CPython optimizes other kinds of loops and iterations (I consider map and list comprehensions as kinds of iteration) better than while loops.

Example: https://www.python.org/doc/essays/list2str

Use intrinsic operations. An implied loop in map() is faster than an explicit for loop; a while loop with an explicit loop counter is even slower.

I have no explanation why you were told to use while loops instead of for loops in VB - I think it normally leads neither to better readable nor to faster code there.


It's because in the typical situation where you want to iterate, python can handle it for you. For example:

>>> mylist = [1,2,3,4,5,6,7]
>>> for item in mylist:
...     print item
... 
1
2
3
4
5
6
7

Similar example with a dictionary:

>>> mydict = {1:'a', 2:'b', 3:'c', 4:'d'}
>>> for key in mydict:
...     print "%d->%s" % (key, mydict[key])
... 
1->a
2->b
3->c
4->d

Using a while loop just isn't necessary in a lot of common usage scenarios (and is not "pythonic").


Here's one comparison from a mailing list post that I though was a good illustration, too:

> 2. I know Perl is different, but there's just no equivalent of while
> ($line = <A_FILE>) { } ?

Python's 'for' loop has built-in knowledge about "iterable" objects, and that includes files. Try using:

for line in file:
    ...

which should do the trick.

Tags:

Python