Loops

Introduction

Suppose we want to print() each item from a list of dog_breeds. We would need to use the following code snippet:

dog_breeds = [‘french_bulldog’, ‘dalmatian’, ‘shihtzu’, ‘poodle’, ‘collie’]

print(dog_breeds[0])
print(dog_breeds[1])
print(dog_breeds[2])
print(dog_breeds[3])
print(dog_breeds[4])

 

This seems inefficient. Luckily, Python (and most other programming languages) gives us an easier way of using, or iterating through, every item in a list. We can use loops! A loop is a way of repeating a set of code many times.

In this lesson, we’ll be learning about:

  • Loops that let us move through each item in a list, called for loops
  • Loops that keep going until we tell them to stop, called while loops
  • Loops that create new lists, called list comprehensions

Create a For Loop

A for loop lets us perform an action on each item in a list. Using each element of a list is known as iterating.

This loop prints each breed in dog_breeds:

dog_breeds = [‘french_bulldog’, ‘dalmation’, ‘shihtzu’, ‘poodle’, ‘collie’]
for breed in dog_breeds:
    print(breed)

 

The general way of writing a for loop is:

for <temporary variable> in <list variable>:
    <action>

 

In our dog breeds example, breed was the temporary variable, dog_breeds was the list variable, and print(breed) was the action performed on every item in the list.

Our temporary variable can be named whatever we want and does not need to be defined beforehand. Each of the following code snippets does the exact same thing as our example:

for i in dog_breeds:
    print(i)
for dog in dog_breeds:
    print(dog)

 

Notice that in all of these examples the print statement is indented. Everything in the same level of indentation after the for loop declaration is included in the for loop, and runs every iteration.

If we forget to indent, we’ll get an IndentationError.

Using Range in Loops

Previously, we iterated through an existing list.

Often we won’t be iterating through a specific list, we’ll just want to do a certain action multiple times. For example, if we wanted to print out a “WARNING!” message three times, we would want to say something like:

for i in <a list of length 3>:
  print(“WARNING!”)

 

Notice that we need to iterate through a list of length 3, but we don’t care what’s in the list. To create these lists of length n, we can use the range function. range takes in a number n as input, and returns a list from 0 to n-1. For example:

zero_thru_five = range(6)
# zero_thru_five is now [0, 1, 2, 3, 4, 5]
zero_thru_one = range(2)
# zero_thru_one is now [0, 1]

 

So, an easy way to accomplish our “WARNING!” example would be:

for i in range(3):
  print(“WARNING!”)

Infinite Loops

We’ve iterated through lists that have a discrete beginning and end. However, let’s consider this example:

my_favorite_numbers = [4, 8, 15, 16, 42]

for number in my_favorite_numbers:
  my_favorite_numbers.append(1)

 

What happens here? Every time we enter the loop, we add a 1 to the end of the list that we are iterating through. As a result, we never make it to the end of the list! It keeps growing!

A loop that never terminates is called an infinite loop. These are very dangerous for your code!

A program that hits an infinite loop often becomes completely unusable. The best course of action is to never write an infinite loop. But if you accidentally stumble into one, you can end the loop by using control + c to terminate the program.

Break

We often want to use a for loop to search through a list for some value:

items_on_sale = [“blue_shirt”, “striped_socks”, “knit_dress”, “red_headband”, “dinosaur_onesie”]

# we want to check if the item with ID “knit_dress” is on sale:
for item in items_on_sale:
  if item == “knit_dress”:
    print(“Knit Dress is on sale!”)

 

This code goes through each item in items_on_sale and checks for a match. After we find that “knit_dress” is in the list items_on_sale, we don’t need to go through the rest of the items_on_sale list. Since it’s only 5 elements long, iterating through the entire list is not a big deal in this case. But what if items_on_sale had 1000 items after “knit_dress”? What if it had 100,000 items after “knit_dress”?

You can stop a for loop from inside the loop by using break. When the program hits a break statement, control returns to the code outside of the for loop. For example:

items_on_sale = [“blue_shirt”, “striped_socks”, “knit_dress”, “red_headband”, “dinosaur_onesie”]

print(“Checking the sale list!”)
for item in items_on_sale:
  print(item)
  if item == “knit_dress”:
    break
print(“End of search!”)

 

This would produce the output:

Checking the sale list!

blue_shirt

striped_socks

knit_dress

End of search!

 

We didn’t need to check “red_headband” or “dinosaur_onesie” at all!

Continue

When we’re iterating through lists, we may want to skip some values. Let’s say we want to print out all of the numbers in a list, unless they’re negative. We can use continue to move to the next i in the list:

big_number_list = [1, 2, -1, 4, -5, 5, 2, -9]

for i in big_number_list:
  if i < 0:
    continue
  print(i)

 

This would produce the output:

1
2
4
5
2

 

Every time there was a negative number, the continue keyword moved the index to the next value in the list, without executing the code in the rest of the for loop.

While Loops

We now have seen and used a lot of examples of for loops. There is another type of loop we can also use, called a while loop. The while loop performs a set of code until some condition is reached.

While loops can be used to iterate through lists, just like for loops:

dog_breeds = [‘bulldog’, ‘dalmation’, ‘shihtzu’, ‘poodle’, ‘collie’]

index = 0
while index < len(dog_breeds):
  print(dog_breeds[index])
  index += 1

 

Every time the condition of the while loop (in this case, index < len(dog_breeds)) is satisfied, the code inside the while loop runs.

While loops can be useful when you don’t know how many iterations it will take to satisfy a condition.

Nested Loops

We have seen how we can go through the elements of a list. What if we have a list made up of multiple lists? How can we loop through all of the individual elements?

Suppose we are in charge of a science class, that is split into three project teams:

project_teams = [[“Ava”, “Samantha”, “James”], [“Lucille”, “Zed”], [“Edgar”, “Gabriel”]]

 

If we want to go through each student, we have to put one loop inside another:

for team in project_teams:
  for student in team:
    print(student)

 

This results in:

Ava
Samantha
James
Lucille
Zed
Edgar
Gabriel

List Comprehensions

Let’s say we have scraped a certain website and gotten these words:

words = [“@coolguy35”, “#nofilter”, “@kewldawg54”, “reply”, “timestamp”, “@matchamom”, “follow”, “#updog”]

 

We want to make a new list, called usernames, that has all of the strings in words with an ‘@’ as the first character. We know we can do this with a for loop:

words = [“@coolguy35”, “#nofilter”, “@kewldawg54”, “reply”, “timestamp”, “@matchamom”, “follow”, “#updog”]
usernames = []

for word in words:
  if word[0] == ‘@’:
    usernames.append(word)

 

First, we created a new empty list, usernames, and as we looped through the words list, we added every word that matched our criterion. Now, the usernames list looks like this:

>>> print(usernames)
[“@coolguy35”, “@kewldawg54”, “@matchamom”]

 

Python has a convenient shorthand to create lists like this with one line:

usernames = [word for word in words if word[0] == ‘@’]

 

This is called a list comprehension. It will produce the same output as the for loop did:

[“@coolguy35”, “@kewldawg54”, “@matchamom”]

 

This list comprehension:

  1. Takes an element in words
  2. Assigns that element to a variable called word
  3. Checks if word[0] == ‘@’, and if so, it adds word to the new list, usernames. If not, nothing happens.
  4. Repeats steps 1-3 for all of the strings in words

Note: if we hadn’t done any checking (let’s say we had omitted if word[0] == ‘@’), the new list would be just a copy of words:

usernames = [word for word in words]
#usernames is now [“@coolguy35”, “#nofilter”, “@kewldawg54”, “reply”, “timestamp”, “@matchamom”, “follow”, “#updog”]

More List Comprehensions

Let’s say we’re working with the usernames list from the last exercise:

>>> print(usernames)
[“@coolguy35”, “@kewldawg54”, “@matchamom”]

 

We want to create a new list with the string ” please follow me!” added to the end of each username. We want to call this new list messages. We can use a list comprehension to make this list with one line:

messages = [user + ” please follow me!” for user in usernames]

 

 

This list comprehension:

  1. Takes a string in usernames
  2. Assigns that number to a variable called user
  3. Adds “ please follow me!” to user
  4. Appends that concatenation to the new list called messages
  5. Repeats steps 1-4 for all of the strings in usernames

Now, messages contains these values:

[“@coolguy35 please follow me!”, “@kewldawg54 please follow me!”, “@matchamom please follow me!”]

 

Being able to create lists with modified values is especially useful when working with numbers. Let’s say we have this list:

my_upvotes = [192, 34, 22, 175, 75, 101, 97]

 

We want to add 100 to each value. We can accomplish this goal in one line:

updated_upvotes = [vote_value + 100 for vote_value in my_upvotes]

 

This list comprehension:

  1. Takes a number in my_upvotes
  2. Assigns that number to a variable called vote_value
  3. Adds 100 to vote_value
  4. Appends that sum to the new list updated_upvotes
  5. Repeats steps 1-4 for all of the numbers in my_upvotes

Now, updated_upvotes contains these values:

[292, 134, 122, 275, 175, 201, 197]

Review

Good job! In this lesson, you learned

  • how to write a for loop
  • how to use range in a loop
  • what infinite loops are and how to avoid them
  • how to skip values in a loop
  • how to write a while loop
  • how to make lists with one line

Let’s get some more practice with these concepts!