Like while loops, for loops will execute an indented code block as long as a condition is met.
The useful aspect of for loops is that this logic does not need to be explicitly determined by the coder. And, you can avoid infinite loops!
Chapter 3.4.1 - Basic for
loop syntax:¶
my_list = [1, 2, 3, 4, 5]
for i in my_list:
print(i)
# do something with i
Each for loop has 3 major components:
iterable
: a data type that is able to interface with afor
loop and has multiple values within it.iteration
: each step in the loop, where theiteration
variable set by the programmer is modified based on values in theiterable
.iterator
: the mechanism that works behind the scenes to set values and determine if the loop should continue
The preconditions for a for
loop require an iterable
data type. These types include (but are not limited to):
list
tuple
dict
Each of these composite data types are considered iterable
, which is just a fancy way of saying that they contain multiple items and a for loop can automatically serve up each item that it contains. For example, an int
is not an iterable
because it is only one value, but a list of int
variables within a list
can be served to a for
loop through the list
that contains these variables.
Each step of the loop (i.e., each time the indented code block is executed) is called an iteration
. During an iteration
, the value served by the for loop changes in the order the values appear in the list.
For example, the following list (which is an iterable
):
my_list = [1, 2, 3, 4]
Would serve to the for
loop the value 1 during the first iteration
. The second iteration
would serve the value 2, and so on.
The iterator
is the magic that occurs in the background of a for loop that does multiple things for you:
It checks to see if there are more items to visit in the
iterable
. If not, the loop endsDuring each
iteration
, it accesses the values in theiterable
at each index in the order in which they appear. Theiterator
then sets this value equal to a variable that is named by the programmer that can be used in the currentiteration
Consider the above for
loop:
my_list = [1, 2, 3, 4, 5]
for i in my_list:
print(i)
# do something with i
The equivalent process can be explicitly demonstrated by a while
loop:
my_list = [1, 2, 3, 4, 5]
index = 0
while (index < len(my_list)):
i = my_list[index]
print(i)
# do something with i
index = index + 1
Notice the extra steps in the while
loop:
- setting an
index
variable to 0 to start at the beginning of the list - determining a condition (i.e.,
index < len(my_list
) when the loop should stop - accessing each value in the list based on the
index
variable and setting it equal to i - incrementing the
index
by 1 to visit the next item in the list, or to cause thewhile
loop condition to result in False and stop the loop.
Thus, for most cases, we would want to use a for
loop to avoid all of the potential pitfalls and bugs that could pop up when using a while
loop.
Examples of the for
and while
loops above.
while
loop:
my_list = [1, 2, 3, 4, 5]
index = 0
while (index < len(my_list)):
i = my_list[index]
print(i)
# do something with i
index = index + 1
1
2
3
4
5
for
loop equivalent
my_list = [1, 2, 3, 4, 5]
for i in my_list:
print(i)
# do something with i
1
2
3
4
5
Chapter 3.4.2 - Iterators¶
There are multiple built-in iterators that are incredibly useful and very common in Python programs. These iterators typically encapsulate common use-cases for steping through iterables (e.g., a list
).
range
¶
One common iteration is to step through a sequence of numbers. For example, you may want to visit all numbers between 1 and 100. Using the code pattern associated with the for
loop above, you might start writing the following code:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 .....]
You immediately recognize that would require typing many numbers. If you have any case where you need 1000, 10000, or 1000000000 number sequences, you can see where this approach would be limiting.
However, Python has a solution--the built-in range
data type. This is a special type of list
that contain a list of int
values with attributes defined by the programmer. Specifically, the programmer can provide the start, end, and steps (i.e., spacing between numbers). This allows you to type as few as two numbers to produce a sequence of many int
values.
The following pattern is associated with range
:
for number in range(start, finish, step):
print(number)
# do stuff with number
Here is a working version below. Modify the start, finish, and step values by typing an int
and pressing enter when prompted below:
start = int(input("start (int): "))
finish = int(input("finish (int): "))
step = int(input("step (int): "))
print(f"for loop output for this loop: for number in range({start}, {finish}, {step})")
for number in range(start, finish, step):
print("number =", number)
# do
# stuff
# with
# number
start (int): 1
finish (int): 10
step (int): 2
for loop output for this loop: for number in range(1, 10, 2)
number = 1
number = 3
number = 5
number = 7
number = 9
Example: # iterate through a list of integers that go from 0 to 10
By default, python will treat using only one number as the “finish” number, and the first number will default to 0 and the step will default to one. The following iterator is equivalent to range(0, 11, 1)
print("for number in range(11):")
for number in range(11):
print(number)
for number in range(11):
0
1
2
3
4
5
6
7
8
9
10
that is much easier than this:
print("for number in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:")
for number in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
print(number)
print("---")
for number in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
0
1
2
3
4
5
6
7
8
9
10
---
Example: iterate through a list of every 10th integer from 0 to 100
print("Output from for number in range(0, 100, 10)")
for number in range(0, 100, 10):
print(number)
Output from for number in range(0, 100, 10)
0
10
20
30
40
50
60
70
80
90
enumerate
¶
Another common pattern is to keep track of how many times the loop has executed. For example, you might have a list of data from hours or days, and you want to print out that the data are from “Day 1” or “Day 2”.
enumerate
will keep track of this information and provide the value during each iteration. This can also be useful for identifying the index associated with each value.
Here is the interactive example above, except with enumerate
included and wrapped around range
:
start = int(input("start (int): "))
finish = int(input("finish (int): "))
step = int(input("step (int): "))
print(f"for loop output for this loop: for number in range({start}, {finish}, {step})")
for idx, number in enumerate(range(start, finish, step)):
print(f"For iteration #{idx}, the value of number is {number}")
# do
# stuff
# with
# number
start (int): 1
finish (int): 10
step (int): 2
for loop output for this loop: for number in range(1, 10, 2)
For iteration #0, the value of number is 1
For iteration #1, the value of number is 3
For iteration #2, the value of number is 5
For iteration #3, the value of number is 7
For iteration #4, the value of number is 9
Chapter 3.4.3 - Stacks and queues¶
These are special types of list
that are used for a specific purpose and various algorithms. This approach uses the pop()
function to remove the last item that was added to the lift (last in, first out) and set it equal to a variable.
Stacks¶
The premise of a stack is Last In First Out (LIFO)
Rules of a stack:
- allow values to be added at any time
- the last value to be added will be the first to be removed when the stack is accessed
stack = []
# print empty stack
print("Empty stack", stack)
# add values to a stack
stack.append(5)
stack.append(4)
stack.append(3)
stack.append(2)
stack.append(1)
# print empty stack
print("Stack with 5 values", stack)
# access values from stack using LIFO
print("First value accesed from stack:", stack.pop())
print("Stack after pop()", stack)
Empty stack []
Stack with 5 values [5, 4, 3, 2, 1]
First value accesed from stack: 1
Stack after pop() [5, 4, 3, 2]
Queue¶
The same as a stack, except the premise of a queue is First in First Out (LIFO)
Rules of a queue:
- allow values to be added at any time
- the first value to be added will be the first to be removed when the queue is accessed (pop(0))
queue = []
# print empty queue
print("Empty queue", queue) # prints []
# add values to a queue
queue.append(5)
queue.append(4)
queue.append(3)
queue.append(2)
queue.append(1)
# print empty queue
print("queue with 5 values", queue) # prints [5, 4, 3, 2, 1]
# access values from queue using FIFO
print("First value accesed from queue:", queue.pop(0)) # prints 5
print("Queue after pop()", queue) # prints [5, 4, 3, 2]
Empty queue []
queue with 5 values [5, 4, 3, 2, 1]
First value accesed from queue: 5
Queue after pop() [4, 3, 2, 1]
Chapter 3.4.5 - Dictionary iterators¶
These follow the same rules as the above examples, except they have different iterator
keywords that need to be explicitly written out:
.keys()
: iterate through only the keys in the dictionary.values()
: iterate only though the values and not the keys in the dictionary.items()
: iterate through BOTH the keys and values
Basic dictionary iterator example:¶
## Basic dictionary iterator example
dict_name = {'test': 1}
for key in dict_name.keys():
print(key) # prints test
for value in dict_name.values():
print(value) # prints 1
for key, values in dict_name.items():
print(key, value) # prints test 1
print("---")
test
1
test 1
---
Example: A weather related use-case that iterates through both keys and values in a dictionary to print a message.
observations = {'temperature': [42, 53, 23, 59, 60], 'dew point': [33, 45, 15, 50, 50]}
for variable, observations in observations.items():
# observations is now a list and can be treated like a list
for temperature in observations:
if temperature >= 32:
print(f"The {variable} is {temperature} F and you should not expect ice!")
else:
print(f"The {variable} is {temperature} F and you should expect ice!")
C = (temperature - 32) * 5/9
K = C + 273.15
print(f"The temperature in celisus is {C:.2f} C and the temperature in Kelvin is {K:.2f} K")
print("")
The temperature is 42 F and you should not expect ice!
The temperature in celisus is 5.56 C and the temperature in Kelvin is 278.71 K
The temperature is 53 F and you should not expect ice!
The temperature in celisus is 11.67 C and the temperature in Kelvin is 284.82 K
The temperature is 23 F and you should expect ice!
The temperature in celisus is -5.00 C and the temperature in Kelvin is 268.15 K
The temperature is 59 F and you should not expect ice!
The temperature in celisus is 15.00 C and the temperature in Kelvin is 288.15 K
The temperature is 60 F and you should not expect ice!
The temperature in celisus is 15.56 C and the temperature in Kelvin is 288.71 K
The dew point is 33 F and you should not expect ice!
The temperature in celisus is 0.56 C and the temperature in Kelvin is 273.71 K
The dew point is 45 F and you should not expect ice!
The temperature in celisus is 7.22 C and the temperature in Kelvin is 280.37 K
The dew point is 15 F and you should expect ice!
The temperature in celisus is -9.44 C and the temperature in Kelvin is 263.71 K
The dew point is 50 F and you should not expect ice!
The temperature in celisus is 10.00 C and the temperature in Kelvin is 283.15 K
The dew point is 50 F and you should not expect ice!
The temperature in celisus is 10.00 C and the temperature in Kelvin is 283.15 K
Chapter 3.4.6 - Practice¶
Create a dictionary
of rock or cloud names, where each name has their affiliated descriptions and a date when you saw the rock or cloud.
Once you complete the dict
, use the dict
iterator to print a message similar to the following:
The cirrus cloud looks wispy and feathery and is usually high in the sky. I saw a cirrus cloud on 09/06/2025.
The obsidian rock is black and shiny and is formed by volcanoes. I saw an obsidian rock on 09/20/2025.