Python while Loop

Chapter 20 10 mins

Learning outcomes:

  1. Syntax of while
  2. Working with while
  3. Combining multiple conditions

Introduction

In the previous chapter on for loop, we saw how to iterate over given iterables using the for statement. Some common iterables we explored included strings and lists.

When the concern is to iterate over a sequence of values i.e an iterable, the for looop works really well. It also works well in counting problems such as repeatedly executing a piece of code for 10 times.

However, sometimes it's required to continue iterating until the point a given condition remains fulfilled.

For instance, we might want to continuously ask the user for an input until he/she enters 'q' to quit the program. The for loop wasn't made to cater to these cases — what we need is the while loop.

Syntax of while

The while loop revolves around the following idea 'while this condition is true, keep doing this set of actions.'

After for, it is the second control flow structure in Python that enables one to perform iteration. Its general form is shown as follows:

while condition:
    # code to execute while condition is True

First comes the while keyword followed by a condition that must evaluate to True in order for the loop to continue iterating.

After this comes a : colon followed by the body of while. Akin to for, this region denotes code that gets executed repeatedly by the loop.

Let's take this into the light of an example.

A simple example

Suppose we want to calculate the remainder when a positive integer a is divided by another positive integer b; without using the % modulus operator (whose sole purpose is to return the remainder).

a = 10
b = 3

The idea is to keep on subtracting b from a, unless what's left behind is lesser than b.

To transform this idea into a while loop, we start by asking ourself the question: what's the condition that must be fulfilled in order to continue with loop. We see that it's for a to be greater than or equal to b, that we must continue iterating.

It's only when a becomes lesser than b, that we stop iterating.

Altogether this gives us the following code:

a = 7
b = 3

while a >= b:
    a -= b

print(a)

The condition is a >= b — if a is greater than or equal to b we continue iterating (to further subtract b from a). In the loop's body, we subtract b from a and reassign the result back to a, using the -= (subtraction-and-assignment) operator.

When the while loop ends, it means that a is now lesser than b and, in effect, the remainder of the division a / b.

Here's the output of the code above:

1

Before each iteration, the condition a >= b is evaluated. If it evaluates to True, the following block of code is executed, otherwise control shifts to the line following the while loop.

Let's go step-by-step for the values of a and b above.

  1. a >= b is evaluated. It returns True, since a = 7 is greater than b = 3.
  2. The loop's body gets executed where a becomes equal to 5 (7 - 3).
  3. Execution shifts back to the header of while, where a >= b is checked again. Once again, it returns True causing the body to be executed again.
  4. a becomes equal to 1 (4 - 3).
  5. Execution returns back to the header, to evaluate a >= b. This time since a = 1 is lesser than b = 2 returns False.
  6. As a result, the loop exits and execution moves to the line after the loop i.e the print() statement.

Combining multiple conditions

As we saw above, often times a while loop is laid out with a single condition to check for. But, sometimes, it's required to check more than one condition.

For instance, while searching for an item in a list, we might want to continue iterating over the list until the item has been found or the end of the list has been reached.

How do you think can we accomplish such tasks of checking for more than one condition?

This can be done using the logical operators or and and.

Recall that or returns True when either of its operands is True, or otherwise returns False. On the other hand, and returns True when both of its operands are True, or otherwise returns False.

Using these, we can construct while loops evaluating more than one condition.

An example follows.

We want to search for an item item in a list l using a function search(). The item goes as the first argument to the function, whereas the list goes as the second .

def search(item, l):
    # function's definition
    pass

The function search() needs to be constructed such that it returns -1 if the item isn't found in the list or else the index of its first occurence.

Most importantly, we aren't allowed to use for to accomplish this, and not even the break keyword. What we're left with is the while loop.

Since, we need to iterate over a list, we need to keep track of each of its indexes. For this, we'll use a variable i. In each iteration, we increment i to point to the next element of the list. When i becomes greater than the last index of the list, we stop.

Furthermore, when the given item is found in the list, i.e l[i] == item, we stop.

So altogether, there are two conditions in which we put the loop to a halt: l[i] == item or i == len(l).

The thing is that in while's header, we have to place the condition that needs to be fulfilled for the loop to continue iterating; not the condition at which the loop shall stop. Above, we've showed the conditions to stop the loop, not the ones to keep it going. To make these conditions we simply need to negate both them — l[i] != item and i != len(l).

Summing all this up, we arrive at the code below:

def search(item, l):
    n = len(l)
    i = 0

    while i < n and l[i] != item:
        i += 1

    return i if i < n else -1

Since len(l) calculates the length of l each time it's called, we save its result inside a variable n to make the loop more efficient. Next, we create i — the counter of the loop — and initialise it to 0.

Then comes the while loop. It performs iteration only if the end of the list hasn't been reached and if item is not equal to the current item of the list. If either of these conditions returns False, the loop stops.

After the while loop, comes the return statement with a conditional expression, where we return i if it's lesser than n, or else the value -1.

Here's what's happening in this conditional expression:

If item doesn't exist in the list, the whole list would get exhausted by the while loop. This means that the body of the loop would get executed n times causing i to be equal to n. If i is lesser than n this means that the list wasn't exhausted i.e a match for item was found, and so we return i.

However, if this is not the case, we return -1.

Let's now call this function on a couple of item and list pairs, and see what we get back.

search(10, [0, 1, 10])
2
search(5, [0, 1, 10])
-1
search(6, [3, 6, 6])
1

In the first call, 10 exists in the list [0, 1, 10] at index 2; likewise we get back 2 returned. In the second call, 5 doesn't exist in [0, 1, 10]; likewise we get -1 returned. In the last call, 6 exists at two locations in the list [3, 6, 6], but what we get back is the index of its first occurence i.e 1.

Everything goes just as we want it to!

Moving on

Iteration is a crucial feature available in almost all modern-day programming languages. It sits at the core of computer automation which itself plays a huge role in the technological era of today.

Knowing how to work with iterations in Python using the for and while loops is thus very important for every developer. It's important that you understand the syntax of these two loops, when to use them, when not to use them, and how to use break and continue within loops.