loops

Table of Contents

1. introduction

  • in programming, loops are used when you want to repeat a specific block of code.
    • for loops, indentation matters in Python.
  • some examples include:
    • finding the average.
    • counting the number of times a specific value appears in a data structure.
    • finding the minimum or maximum value.
  • two main types of loops in python include while and for loops. let’s briefly go over them.

2. while loops

  • executes while a a specific condition is True.
    • once the condition is False, the loop ends/terminates.
  • the condition is checked before each loop iteration.
    • if the condition is initially False, then the code block will not execute (AKA skipped over).
    • if the condition never becomes False, then an infinite loop occurs.
      • this can be prevented by changing a variable within the loop body that is within the loop’s condition.
  • use a while loop when:
    • the number of iterations required is not known beforehand.
    • condition-based rather than numerical-based.
  • while loops also support an optional else block.
    • executes once only if the loop’s condition becomes False and the loop terminates normally (without the use of a break statement).
  • sentinel value = value that causes a loop to end.
  • here are a few while loop examples:
# while loop
# if i never incremented, this loop would enter an infinite loop because
# i would never be greater than 5.
# this example closely emulates what a for loop does:
# - i is set to an initial value, 1 (start)
# - the while loop stops when i is greater than 5 AKA becomes equal to 6 (stop)
# - the while loop increments by 1 during each iteration (step)
i = 1
while i <= 5:
    print(i)
    i += 1 # i is incremented during each iteration.

# prints out numbers 1-5.

# while loop with else block
# since the while loop terminates normally, the code in the else block is executed.
j = 0
while j < 3:
    print(j)
    j += 1
else:
    print("no break statement was used.")

# prints out numbers 0-2 and "no break statement was used."

# since the while loop terminates using a break statement,
# the code in the else block is not executed.
k = 1
while k < 4:
    print(k)
    k += 1
    if k == 3:
        break
else:
    print("no break statement was used.")

# prints out numbers 1-2.

# in this case, "q" is the sentinel value because it causes the while loop to end.
sentinel_value = "q"
user_input = input("quit out of this while loop by entering 'q': ")

while user_input != sentinel_value:
    print("still in the loop! ")
    user_input = input("quit out of this while loop by entering 'q': ")

print("no longer in the loop")

# let input be:
# no
# q

# prints out:
# quit out of this while loop by entering 'q':
# still in the loop!
# quit out of this while loop by entering 'q':
# no longer in the loop
        

3. for loops

  • typically used to iterate over iterable objects, such as lists, tuples, strings, etc.
  • typically used in combination with the range() function, which returns an iterable object.
  • allows for processing elements in a container one by one.
    • ex: appending a specific number of items to a list based on user input.
  • the loop automatically terminates when all items in the iterable have been processed.
  • two types of looping:
    • looping by index
    • looping by value
  • use a for loop when:
    • you know the number of times you want to iterate through a code block.
    • you want to iterate over the indices or values of some data structure.
  • typically preferred over while loops when possible so you don’t have to deal with infinite loops.
  • similar to while loops, for loops also have an optional else block.
    • the else code block only executes if the loop terminates normally without encountering a break statement.
  • here are a few for loop examples:
print("simple for loop:")

# for loop
for i in range(5):
    print(i)

# prints out numbers 0-4.

print()
print("looping by index:")

# for loop using an iterable data structure (works for lists, tuples, strings, etc.)
a_list = [1, 2, 3, 4, 5]

# looping by index
for i in range(len(a_list)):
    print(i)

# prints out numbers 0-4.

print()
print("looping by index to access elements:")

# can use looping by index to to access list elements
for i in range(len(a_list)):
    print(a_list[i])

# prints out numbers 1-5.

print()
print("looping by value:")

# looping by value
# use this when you only need the values and not the indices of an iterable data structure.
for element in a_list:
    print(element)

# prints out numbers 1-5.

print()
print("looping by value using a list copy:")

# can iterate over a copy of a list using [:], which creates a shallow copy of the list.
# useful when you want to modify values in the list without the list size changing.
for element in a_list[:]:
    print(element)

# prints out numbers 1-5.

print()
print("looping by index and value using enumerate() function:")

# can use the enumerate() function to access both the index and its respective value.
for index, value in enumerate(a_list):
    print(str(index) + ", " + str(value))

# prints out numbers 1-5 and their corresponding index.
        
simple for loop:
0
1
2
3
4

looping by index:
0
1
2
3
4

looping by index to access elements:
1
2
3
4
5

looping by value:
1
2
3
4
5

looping by value using a list copy:
1
2
3
4
5

looping by index and value using enumerate() function:
0, 1
1, 2
2, 3
3, 4
4, 5
  • since dictionaries are unordered, key-value pairs are accessed rather than elements via index.
  • here are a few dictionary for loop examples:
print("iterating over keys:")
# new dictionary object
a_dict = {"a": 1, "b": 2, "c": 3}

# when a_dict alone is used as the iterable in a for loop,
# the keys are being iterated rather than the values.
for key in a_dict:
    print(key)

# prints out characters a-c.

print()
print("iterating over keys using keys() method:")

# alternatively, you can also use the keys() method,
# which returns an object containing the dictionary's keys.
# this is typically preferred over the previous example for readability purposes.
for key in a_dict.keys():
    print(key)

# prints out characters a-c.

print()
print("iterating over values using values() method:")

# if you want to iterate over the dictionary's values, you can use the values() method.
for value in a_dict.values():
    print(value)

# prints out numbers 1-3.

print()
print("iterating over keys and values using items() method:")

# if you want to have access to both the dictionary's keys and corresponding values,
# you can use the items() method.
for key, value in a_dict.items():
    print(key + ", " + str(value))

# prints out keys a-c and their corresponding values.

iterating over keys:
a
b
c

iterating over keys using keys() method:
a
b
c

iterating over values using values() method:
1
2
3

iterating over keys and values using items() method:
a, 1
b, 2
c, 3

4. for _ in range() loops

  • lets go into more detail about the range() function’s capabilities.
  • can take up to 3 arguments (in this order):
    • start
      • defaults to 0 if not specified.
      • inclusive.
    • stop
      • exclusive.
    • step
      • defaults to 1 if not specified.
  • if one argument is specified, then:
    • start = 0
    • stop = given argument
    • step = 1
  • if two arguments are specified, then:
    • start = argument 1
    • stop = argument 2
    • step = 1
  • if three arguments are specified, then:
    • start = argument 1
    • stop = argument 2
    • step = argument 3
  • here are a few for _ in range() examples:
print("for loop with range(4):")

# the stop value is always excluded
for i in range(4):
    print(i)

# prints out numbers 0-3.

print()
print("for loop with range(3, 7):")

for i in range(3, 7):
    print(i)

# prints out numbers 3-6.

print()
print("for loop with range(0, 5, 2):")

for i in range(0, 5, 2):
    print(i)

# prints out all even numbers from 0-4.

print()
print("for loop with range(5, 0, 2):")

# if the stop is less than or equal to the start and the step is positive,
# range() will return an empty sequence.
for i in range(5, 0, 2):
    print(i)

# won't print anything.

print("won't print anything.")
print()
print("for loop with range(5, 0, -1):")

# supports negative step
for i in range(5, 0, -1):
    print(i)

# prints out numbers 5-1 in descending order.

print()
print("for loop with range(0, 5, -1):")

# if the stop is greater than or equal to the start and the step is negative,
# range() will return an empty sequence.
for i in range(0, 5, -1):
    print(i)

# won't print anything.

print("won't print anything.")
print()
print("for loop with _ and range(6):")

# can optionally use _ instead of a variable if the value of range()
# during each iteration is not needed for your code to execute.
for _ in range(6):
    print("hi")

# prints out "hi" 6 times.
        
for loop with range(4):
0
1
2
3

for loop with range(3, 7):
3
4
5
6

for loop with range(0, 5, 2):
0
2
4

for loop with range(5, 0, 2):
won't print anything.

for loop with range(5, 0, -1):
5
4
3
2
1

for loop with range(0, 5, -1):
won't print anything.

for loop with _ and range(6):
hi
hi
hi
hi
hi
hi

5. break and continue

  • statements used to change the normal flow of execution within both for and while loops.
  • break statement immediately terminates the loop.
    • program resumes at the statement following the loop.
    • typically used when a specific condition is met within the loop.
  • continue statement skips the rest of the current iteration of the loop.
    • program execution continues to the next iteration, reevaluating the loop’s condition (for while loops) or moving on to the sequence’s next item (for for loops).
    • typically used when you want to skip parts of the loop’s code but want the loop to continue with following iterations.
  • here are a few loop examples using break and continue:
print("for loop with continue:")

# for loop with continue
for i in range(10):
    if i % 2 == 1:
        continue
    print(i)
print("printing even integers between 0-8 completed")

# prints out all even numbers from 0-8 and "printing even integers between 0-8 completed".

print()
print("for loop with break:")

# for loop with break
for i in range(1, 10):
    if i == 6:
        print("broken loop at:", i)
        break
    print(i)
print("printing integers 1-5 completed")

# prints out numbers 1-5, "broken loop at: 6", and "printing integers 1-5 completed".

print()
print("while loop with break:")

# while loop with break
count = 0
while count < 10:
    print(count)
    if count == 4:
        print("broken loop at count:", count)
        break
    count += 1
print("printing integers 0-4 completed")

# prints out numbers 0-4, "broken loop at count: 4", and "printing integers 0-4 completed".

print()
print("while loop with continue:")

# while loop with continue
number = 0
while number < 5:
    number += 1
    if number == 3:
        print("skipping number:", number)
        continue
    print(number)
print("printing integers 1-5 excluding 3 completed")

# prints out numbers 1-2, "skipping number: 3", numbers 4-5,
# and "printing integers 1-5 excluding 3 completed".
        
for loop with continue:
0
2
4
6
8
printing even integers between 0-8 completed

for loop with break:
1
2
3
4
5
broken loop at: 6
printing integers 1-5 completed

while loop with break:
0
1
2
3
4
broken loop at count: 4
printing integers 0-4 completed

while loop with continue:
1
2
skipping number: 3
4
5
printing integers 1-5 excluding 3 completed

6. nested loops

  • placing one loop inside of another loop.
  • the inner loop completes all of its iterations for every iteration of the outer loop.
  • the inner loop’s clause must be indented in relation to the outer loop.
    • the inner loop’s statements must be further indented.
  • use nested loops when:
    • iterating over multi-dimensional data structures (ex: nested lists).
    • executing repeated action that involve multiple iterations at once.
  • here are a few nested loop examples:
print("nested for loops: ")

# nested for loops
for i in range(1, 4):
    for j in range(1, 4):
        print(f"{i} * {j} = {i * j}")
    print("-" * 10) # separator

# prints all multiplication equations where the factors are numbers 1-3.

print()
print("nested while loops: ")

# nested while loops
rows = 3
i = 1
while i <= rows:
    j = 1
    while j <= i:
        print("*", end="")
        j += 1
    print() # new line after each row
    i += 1

# prints out a 3 by 3 right triangle using asterisks.

print()
print("iterating through a nested list: ")

# iterating through a nested list
condition = True
count = 0
nested_list = [["apple", "banana"], ["carrot", "date"], ["eggplant", "fig"]]

while condition:
    print(f"outer loop: {count}")
    for row in nested_list:
        for item in row:
            print(f" - {item}")
    count += 1
    if count >= 2:
        condition = False

# prints out all elements in the nested list twice,
# keeping track of the outer loop's variable value.
                
nested for loops: 
1 * 1 = 1
1 * 2 = 2
1 * 3 = 3
----------
2 * 1 = 2
2 * 2 = 4
2 * 3 = 6
----------
3 * 1 = 3
3 * 2 = 6
3 * 3 = 9
----------

nested while loops: 
*
**
***

iterating through a nested list: 
outer loop: 0
 - apple
 - banana
 - carrot
 - date
 - eggplant
 - fig
outer loop: 1
 - apple
 - banana
 - carrot
 - date
 - eggplant
 - fig

Author: Ashley Pock

Created: 11/10/2025 Mon