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
indexvariable to keep track of the current index inmy_listthat we’re going to check, and we usecontains_negativeto 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_negativeaccordingly. Then, it incrementsindexso in the next (potential) iteration of the loop, the next index ofmy_listwill be checkedThe loop continues iterating until the loop condition is
False, which happens when eithercontains_negativeisTrueorindex>= 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!