Searching with while loops#
We’ve searched through a list in the “Finding something in a list” challenge, using for loops. And we’ve also met the in
operator. We can also use while loops to iterate over a list and check if it contains something we’re interested in. For example, say we had a list of integers and wanted to know if any of the elements are negative. It’s possible to use a for loop for that, but in
would be tricky. Then, we could do something like the following:
Let’s break down the pieces of this:
We use the
index
variable to keep track of the current index inmy_list
that we’re going to check, and we usecontains_negative
to store whether or not we have found a negative number inmy_list
.The loop body checks whether or not the element at
my_list[index]
is negative or not, and updatescontains_negative
accordingly. Then, it incrementsindex
so in the next (potential) iteration of the loop, the next index ofmy_list
will be checkedThe loop continues iterating until the loop condition is
False
, which happens when eithercontains_negative
isTrue
orindex
>= the length ofmy_list
This loop will keep iterating until contains_negative
is updated to be True
when -8
at index 2 is determined to be negative. Once contains_negative
changes to True
, index
is then incremented and we check the loop condition again. The condition will evaluate to False
because not contains_negative
evaluates to False
, and so we exit the loop.
What if, instead, our list was the following:
my_list = [1, 6, 8, 2, 11]
Since we don’t have any negative numbers, the loop will instead exit when index
is no longer smaller than the length of the list (index < len(my_list)
evaluates to False
). This is why we need this second loop condition. If we didn’t have it, the loop would continue and try to access an index that’s out of bounds of the list.
Common mistake: off-by-one errors#
But wait, if we want to check the whole list, why are we checking if index < len(my_list)
instead of index <= len(my_list)
? This is because if we had instead used <=
, we would be trying to check one element too many. Recall that the last valid index of a list is one less than the length of a list (e.g. the index of the last element of my_list
is 4, but its length is 5). We would have gone through the loop body one more time than we should have if we used <=
. This is a very common type of mistake to make, and is classified as an off-by-one error, because we would have been off by one from the correct number of times we should have executed the loop. Off-by-one errors often occur due to logical errors in loop conditions, so stay on your toes!