11.3. The while loop

The while loop

A while loop is composed of two parts, a condition and a sequence of statements to repeat. During the execution, the sequence of statements are repeated as long as the condition is true. Figure 11.2 illustrates the flow of execution.

Figure 11.2. Flow of execution of a while statement

Before saying more, let us illustrate that with an example. We have already shown how to use the find method of strings to find pattern (Section 1.1). Let's try now to find all occurrences of a specific pattern in a DNA sequence. Here is one possible way to proceed:

Procedure 11.6. Find all occurrences of a pattern in a sequence

INPUT: a DNA sequence seq and a pattern pat

OUTPUT: a list of positions matches containing all start positions of pat in seq

  1. matches <- empty list
  2. current_match <- position of the first occurrence of pattern pat in sequence seq or -1 if there is not anyone
  3. as long as current_match is not -1:
    1. matches <- matches + current_matches
    2. current_match <- position of the next occurrence of pattern pat in sequence seq after current_match or -1 if there is not anyone
  4. return matches

Example 11.2. First example of a while loop

And here is the implementation in Python:

	
def findpos(seq, pat):
    matches = []
    current_match = seq.find(pat)
    while current_match != -1:
        matches.append(current_match)
        current_match =seq.find(pat, current_match+1)
    return matches

      

In Python a while loop is written using the while statement which is as the for and the if statements a block statement. The header of the block statement contains the conditional expression and the body contains the sequence of statements to repeat (Figure 11.3).

Figure 11.3. Structure of the while statement

Look at the following example. Do you know what happened during the execution?

while 1:
   print "hello"
    
It simply never stops, because 1 is always true and therefore it is neither an algorithm nor a program. But it illustrates an important feature of a while loop. The conditional expression has to contain at least one variable whose value changes during the execution of the sequence of statements.

This variable is often a simple iterator, which is increased or decreased until it reaches a limit. The behavior of the current_match variable in Example 11.2 is more complicated, because it represents two situations. Its value is the start position of a pattern occurrence or it is -1 if there are no more occurrences. In this example the second argument of the find function ensures that the next occurrence is found but no occurrence missed.

Because the iteration variable is used in the condition and the condition is evaluated first when a while loop is entered, it has to be defined before entering the loop. This means there are two different affectations of this variable. A first affectation or initialization before the loop is entered and a second affectation statement in the repeated sequence of statements that gives it the next value. In general, this is the last statement of the sequence. Even if it is not always the case, and sometimes not necessary, it is a convention to put it at the end if possible because it is easy to find if it has been forgotten.

Warning

Conditions of while loops are frequent source of errors. They are sometimes difficult to detect because they are semantic errors that produce wrong results on all or sometimes only special input data sets. You have to ensure that the iteration variable changes and that the end condition is always reached.

The following example illustrates a common use of the while construct to get input from an interactive user:

en2fr = {
    'comma': 'virgule',
    'hyphen': 'tiret',
    'colon': 'deux-points'
}
x = raw_input("Enter an English word (hit return to finish): ")
while x != "":
    if en2fr.has_key(x):
       print en2fr[x]
    else:
       	print x, "does not exist"
    x = raw_input("Enter an English word (hit return to finish): ")
      
This loop uses what is called a sentinel, a special value to indicate the end of the input. The sentinel has to be chosen in order to be a value that does not belong to the collection.