3.1. Introduction to Loops#

3.1.1. Covered in this Chapter#

  1. What are Loops?

  2. Iterations

  3. Why are Loops Important?

  4. For Loops

  5. While Loops

3.1.2. What are Loops?#

Loops are a fundamental concept in all programming languages. They are essential in nearly every piece of code that I write and my experience is far from unique. Loops are essential because they allow you to systematically iterate over data. Iteration is the process by which you move across a piece of data or collection of data. As we will learn in this chapter, there are two types of loops in Python:

  1. For Loops

  2. While Loops

While most tasks can be achieved with either loop, the way in which you use them is different. By the end of this chapter, you will understand not only how to construct a loop in Python, but have a general idea about when to use which loop. As you code more and more, you will learn that coders tend to favor one type of loop over the other. For me (pun intended), I prefer the for loop. If you asked me why, I could not give you an answer. Maybe by the end of this chapter, you will have a favorite as well!

3.1.3. For Loops#

A good way to think about a for loop is to first imagine in your mind a list of names:

Tom, Nancy, Drew, Steph

Notice that in our list above, we have four names. Each name is separated by a comma. The for loop allows us to move across this list where each comma occurs. Still to this day, when I write a for loop, I say the following in my mind:

“For each item in this list, do something.”

Let’s imagine that we wanted to use Python to print off each of the names. I would say in my mind:

“For each item in this list, print off the name”.

I have not written a single bit of code, rather expressed a type of logic, or series of operations in regular English. This is known as pseudo-code. Pseudo-code is a great way to thinking about code because it is language-agnostic. By this I mean that the same pseudo-code can be applied to Python and C alike. It is useful to think about psudeo-code because it focuses on the logic of the statements, not the code. As you write more complex programs, you will find that it is not always the programming language that is difficult and produces errors, rather the logic behind how you have rendered that language. Pseduo-code lets you first figure out the logic of what you want to do, then you can focus on the execution of that logic.

The above statement in English (“For each item in this list, print off the name”.) will not work if I write it in a Python file, but it allows for me to get the logic of what I want to do down on paper. Next, I would need to write out this logic into normal Python syntax. Let’s try and do that now.

First, let’s make a list of names by creating an object named name_list. You may also want to call this variable nameList. Either convention is fine.

name_list = ["Tom", "Nancy", "Drew", "Steph"]

Great! Now that we have our name_list variable, let’s try and iterate over it, or pass over each item in that list. To do this in Python, we would write something like this:

for name in name_list:
    print(name)
Tom
Nancy
Drew
Steph

Let’s break down a series of things that are happening here. We start off by writing “for”. This tells Python that we are about to enter a for loop and that it should check for proper syntax. Next, we have the word “name”. This is a variable that will point to an object created in memory. It will be changed each time the loop iterates over the next item in the expression, “name_list”. This word “name_list” corresponds to the object name that I want to iterate over. Finally there is a “:”. In Python, this is the way that we note a nested portion of code. We will use these in nearly every script we write because we frequently need to nest items in code. Once Python sees a “:”, it will expect the next line to be indented.

On the next line, we have an indent followed by print. If you remember correctly, the print function allows us to print something off in our output. Next, we have what we want to be printed, the variable “name”. In other words, we want each name that is temporarily created in memory to be printed off.

Notice in the block of code below, I have changed the object “name” to “item”. The name here does not matter. It is simply a word that will indicate the name of the object that you are creating. It is considered Pythonic, or good form, to select a name for the object that makes sense. Because this is a name_list, it makes sense to use the word “name” for that object name so that others who read your code will understand it better.

for item in name_list:
    print (item)
Tom
Nancy
Drew
Steph

While being able to print things off in a for loop is useful, especially when debugging, usually for loops are used to modify data in some capacity. In the cell below, I want to be able to create a new list based on the list of names in namelist. However, I know that all individuals in that list have the last name “Mattingly”. I could manually add the last name Mattingly to each individual person, but that would be tedious and, if I had a list of thousands of names, impractical.

Within the for loop, therefore, I want to modify the existing string and add it to the new list, “new_names”. We can modify a string in several ways. For now, we will use the simpler approach of simply adding a plus sign (+) between the object name and the new piece of information I want to add to it, ” Mattingly”

new_names = []
for name in name_list:
    print (name+" Mattingly")
    new_names.append(name+" Mattingly")
Tom Mattingly
Nancy Mattingly
Drew Mattingly
Steph Mattingly

Now that we have executed the cell above, let’s see how our new list looks. Let’s print it off.

print(new_names)
['Tom Mattingly', 'Nancy Mattingly', 'Drew Mattingly', 'Steph Mattingly']

Viola! Like magic, we have brought two different pieces of data together in a for loop.

3.1.4. List Comprehension#

Sometimes in someone’s code you will see this same idea expressed in a single line of code. It will look like this:

new_names_comprehension = [name+" Mattingly" for name in name_list]
print(new_names_comprehension)
['Tom Mattingly', 'Nancy Mattingly', 'Drew Mattingly', 'Steph Mattingly']

This is known as list comprehension. List comprehension is a way of creating a list on a single line with a loop appearing within the open and close brackets. This single line does precisely the same thing as the four line of code above, but allows a programmer to express it in tighter code. Tighter code is a phrase often used to describe code that is more concise. This is often what polished, final code should look like and it is a style in which computer scientists in particular try to write. While tighter code is often considered more polished, it can be more difficult for other humanists or novice programmers to understand. Like writing in a spoken language, the purpose of writing in code is also to be readable. You should know your audience. If your audience are those who are not computer scientists, perhaps writing more verbose code is better.

Let’s parse out the components of this single line. First, we have the object that we want to create with the variable name “new_names_comprehension” we set this equal to an open bracket. Within this open bracket we state what we want to do to the temporary variable created across the loop. In this case, that variable is again “name”. Again, we specify that we want to add ” Mattingly” to that variable name. Next, we specify the loop, e.g. “for name in name_list”. Finally, we use a closed bracket to indicate the end of that statement.

For now, focus on being more verbose and writing out your code as seen in the first example. This will help you get the logic down and debug issues as they surface more easily as your bugs will appear on a specific line that caused the error. When you get more comfortable with Python, then try to use list comprehension.

I am including list comprehension here not so that you use it, but so that you will see it here first in a controlled setting. You will likely see this in GitHub repositories and on StackOverflow with little explanation. Now that you have seen what list comprehension looks like and understand its components, you will be able to parse that code a bit more easily.

3.1.5. Indexing a List with and without Enumerate#

Often when we create a loop, we need to understand where we are in a specific index of a list. As you will find with programming, there are multiple ways to do this.

Let’s explore a simple approach first so that you can understand the logic behind the approach. Next, we will see a cleaner, but more complex example.

i = 0
for name in name_list:
    print(i)
    print(name)
    i=i+1
0
Tom
1
Nancy
2
Drew
3
Steph

In the above example, everything is nearly identical to our initial for loop with one clear addition, the variable “i”. The name “i” here represents a counter that we are storing outside of our loop. We initially set this variable to 0. As we iterate over our loop, we conclude each pass with the code “i=i+1”. This command says to Python take the object “i” and whatever that number is add 1 to it. This means that each time we pass over our name_list, we know precisely where we are in the index.

We can write this exact same code, however, by using the built-in function “enumerate”. Enumerate automatically creates a variable for us during our loop and ticks it up each time we pass over an item in the list. We can use enumerate to write cleaner and tighter code.

for i, name in enumerate(name_list):
    print(i)
    print(name)
0
Tom
1
Nancy
2
Drew
3
Steph

Notice that we have the precise same result as above. Let’s break down precisely what is happening in this example.

The only thing that has changed is the following line:

for i, name in enumerate(name_list):

Notice the addition of ‘i, name’. This means that we have two variables that we will be creating each time we loop. When using enumerate, the very first variable should always be ‘i’ or something that points to the integer that will count up. Next, we have a comma. This separates the two variables out in the loop. Next, we have the item in the list that we create as we iterate over our data. This is the same variable name that we used before, ‘name’. Finally, we have ‘enumerate(name_list):’ This tells Python to use enumerate on the name_list. The enumerate function is what creates the i for us in memory.

In the area below, try to create your own list and iterate over it. Next, try to use enumerate and print off the index of each item in the list.

Hide code cell source
from IPython.display import IFrame
IFrame("https://trinket.io/embed/python3/524597417f", 700, 356)

3.1.6. Operators#

In Chapter 02-01, we met briefly operators. I mentioned them there so that you were aware of them and because they most often associated with numbers, but as we will see, these can be used on all types of data. We will very often in loops need to identify Comparison Operators (equal to, less than, etc). Here is a list of those:

  1. Equal to (==)

  2. Greater than (>)

  3. Less than (<)

  4. Less than or equal to (<=)

  5. Greater than or equal to (>=)

  6. Not equal to (!=)

Operators allow us to return a Boolean (True or False) about the question we pose with them. Say, for example, we wanted to know if 1 was less than 2. This is True, but in Python we could structure it like so:

print (1 < 2)
True

We could also structure the false statement of if 1 is greater than 2.

print (1 > 2)
False

Or even if 1 is equal to 2. Notice the double = here. We have to use two = because one = in Python sets up a new variable.

print (1 == 2)
False

In math, we use an equal sign with a slash through it to state not equal to, but in code that does not work so cleanly because it is not a character on the keyboard. Instead, we use !=. Believe it or not, you will get really good about writing != over time. If we wanted to see if 1 is not equal to 2, we would write this:

print (1 != 2)
True

On the surface, it may seem like you would never need to use comparison operators. You know that 1 is not equal to 2. In fact, you will use them all the time because comparison operators allow for you to leverage Boolean logic, or True-False logic. This is particular useful in loops. A good way to demonstrate this is with a while loop.

3.1.7. While Loops#

These operators allow us to structure complex conditions within our loop. So, we can say that while something is equal to something else, Python should do x. We will see this same concept in the following chapter as we explore conditionals. I think the best way to learn about this concept is to jump in and explore it.

In the for loop, the loop iterated over a set of data. A while loop is a bit different. In a while loop, the loop will run continuously while something is true. Like the for loop, we create the loop with a set of commands beginning with its name, while. Next we state the condition to be met that will result in breaking, or stoping the loop. Let’s say we wanted to count from 0 to 10. We would create an object named x and set that equal to our start position. Then we would state so long as x != (not equal to) 10, print off x. In order to ensure that x ticks up, we need to make sure that we change the object from x to x+1 so that it moves up by 1 number each time.

x=0
while x != 10:
    print (x)
    x=x+1
0
1
2
3
4
5
6
7
8
9

I know I have stated this before, but it is worth mentioning again. In coding, there us usually never one way to do a task. Notice in the block of code below what is different? Why don’t you take a look at it and see if you can figure out precisely what is happening and why it succeeds in performing the same task.

x=0
while x < 10:
    print (x)
    x=x+1
0
1
2
3
4
5
6
7
8
9

3.1.8. Quiz#

Hide code cell source
quiz = '''
# Which of the following is an operator?
mc
* <
-c t
-f

* >
-c t
-f

* =
-c f
-f Close. Remember = is used in Python to create a variable. == is it's operator form.

* !=
-c t
-f

# What are the two kinds of loops in Python?
mc

* For
-c t
-f

* While
-c t
-f

* If
-c f
-f

* Then
-c f
-f

'''
from jupyterquiz import display_quiz
import md2json
import json
myquiz = md2json.convert(quiz)
myquiz = json.loads(myquiz)
display_quiz(myquiz)