Python Loop Patterns

In the last lesson you learned Nested Loops, where one loop runs inside another. Now we zoom back out to single loops. Let’s look at the jobs you will give them again and again. Most real loops are not random. They follow a handful of shapes that show up everywhere. Once you know these shapes, you can solve a huge range of problems. You just pick the right one.

πŸ€” Why Learn Loop Patterns?

Picture this. You have a list of prices and you need the total. Then someone asks how many of them are above 100. Then they want the most expensive one. Each time you sit and build the loop from scratch. And each time you make a small mistake.

That is the pain. A loop pattern is a ready-made shape for a loop that does one common job. It might add things up. It might find the biggest one. Learn the shape once. Then reuse it for the rest of your coding life.

These are the patterns we will walk through:

  • Running a total (sum)
  • Counting items that match a condition
  • Finding a maximum or minimum
  • Building a brand new list while looping
  • Looping with both the position and the value, using enumerate()

Let’s look at each one with a small, real snippet.

βž• Running a Total

This is the most common pattern of all. You start a variable at zero. Then you add each item to it as you loop. By the end, that variable holds the total. People call this an accumulator, because it accumulates. It keeps gathering more.

Here we add up a list of daily step counts to get the weekly total.

steps = [4200, 8100, 6500, 9000, 3300]
total = 0
for count in steps:
total = total + count
print(f"Total steps this week: {total}")

Read it line by line:

  • total = 0 sets up the accumulator. We start at zero because nothing has been added yet.
  • for count in steps: walks through the list one number at a time.
  • total = total + count takes whatever we had and adds the current number to it.
  • After the loop ends, total holds everything added together.

Output

Total steps this week: 31100

The key idea is the starting value. For a sum you start at 0. Adding zero to your first number changes nothing. If you start at the wrong value, every result after that is off.

Tip

Python has a built-in sum() for plain addition, so sum(steps) gives the same answer. But the manual loop is worth knowing. You will need it when the rule is more than simple adding, like β€œadd only the prices above 100”.

πŸ”’ Counting Items That Match

Sometimes you do not want the total. You want a count of how many items pass a test. The shape is almost the same. But instead of adding the value, you add 1 every time the condition is true.

Here we count how many test scores are a pass. A pass means 50 or higher.

scores = [72, 45, 90, 38, 50, 66]
passes = 0
for score in scores:
if score >= 50:
passes = passes + 1
print(f"Number of passes: {passes}")

Walking through it:

  • passes = 0 is our counter, starting at zero.
  • if score >= 50: is the test. Only scores that are 50 or more count.
  • passes = passes + 1 runs only when the test is true. So the counter goes up by one for each pass.
  • Scores below 50 are simply skipped.

Output

Number of passes: 4

Notice the difference from a running total. A sum adds the value itself. A count adds 1 no matter what the value is. So passes = passes + 1 is the heart of every counting loop.

πŸ“ˆ Finding a Maximum or Minimum

Now you want the biggest or the smallest item. The trick here is the starting value again, but with a twist. You start by assuming the first item is the winner. Then you let the loop challenge that guess.

Here we find the highest temperature in a list of readings.

temps = [21.5, 19.0, 24.8, 22.1, 18.6]
highest = temps[0]
for temp in temps:
if temp > highest:
highest = temp
print(f"Highest temperature: {highest}")

Here is what happens:

  • highest = temps[0] starts our guess at the first reading. We have to start somewhere, so we start with a real value from the list.
  • if temp > highest: asks, is this reading bigger than the best one so far?
  • highest = temp updates our guess only when we find something bigger.
  • By the end, highest holds the largest value the loop ever saw.

Output

Highest temperature: 24.8

For a minimum, you flip one thing. Start lowest = temps[0]. Then change the test to if temp < lowest:. Same shape, opposite question.

Caution

Do not start a maximum search at highest = 0. If all your numbers are negative, like -5 and -9, then 0 is bigger than all of them and your answer is wrong. Starting from the first real item is the safe habit. Python also has built-in max() and min(), but knowing the loop lets you add custom rules later.

🧱 Building a New List

This pattern is special. Instead of producing one number, you produce a whole new list. You start with an empty list. Then you append() a new item on each turn of the loop. The append() method adds one item to the end of a list.

Here we take a list of names and build a new list of greetings.

names = ["Alex", "Riya", "Arjun"]
greetings = []
for name in names:
greetings.append(f"Hi {name}!")
print(greetings)

Step by step:

  • greetings = [] creates an empty list, ready to be filled.
  • The loop visits each name in turn.
  • greetings.append(f"Hi {name}!") builds a greeting string and adds it to the end of the new list.
  • The original names list is untouched. We made something new from it.

Output

[β€˜Hi Alex!’, β€˜Hi Riya!’, β€˜Hi Arjun!’]

You see this shape everywhere. Turn a list of prices into prices with tax. Turn a list of words into their lengths. Turn a list of users into just their emails. The pattern is always the same: start empty, loop, append.

πŸ—‚οΈ Looping With Index and Value: enumerate()

Often you want to know more than just the value. You also want its position in the list. The position, counting from zero, is called the index. You could track it yourself with a counter. But Python gives you a cleaner tool called enumerate(). It hands you both the index and the value on every turn.

Here we print a numbered list of tasks.

tasks = ["Buy milk", "Call Riya", "Finish report"]
for index, task in enumerate(tasks):
print(f"{index}: {task}")

What is going on:

  • enumerate(tasks) wraps the list so each turn gives back two things: the index and the item.
  • for index, task in ... unpacks those two things into two variables at once.
  • index is the position, starting at 0, and task is the value at that position.

Output

0: Buy milk 1: Call Riya 2: Finish report

What if you would rather count from one, like a human list? enumerate() takes a start value. Use enumerate(tasks, start=1) and the first index becomes 1 instead of 0. That is much nicer to read than tracking your own counter and remembering to add one to it.

πŸ“‹ The Patterns at a Glance

Here is a quick map so you can pick the right shape fast.

You want Start with Inside the loop
A total total = 0 total = total + item
A count count = 0 if test: count = count + 1
The biggest best = items[0] if item > best: best = item
A new list result = [] result.append(...)
Index and value nothing extra for i, v in enumerate(items):

⚠️ Common Mistakes

A few traps catch people over and over with these patterns.

  • Putting the starting value inside the loop. If total = 0 sits inside the for block, it resets to zero on every turn and you lose your running total.
# ❌ Avoid: total resets every turn, final answer is just the last item
for count in steps:
total = 0
total = total + count
# βœ… Good: set the starting value once, before the loop
total = 0
for count in steps:
total = total + count
  • Starting a maximum at 0. As we saw, negative numbers break this. Start at the first real item instead.

  • Appending to the wrong list. If you append() to the original list instead of a new empty one, you grow the very list you are looping over. That causes strange results.

# ❌ Avoid: changing the list you are looping over
for name in names:
names.append(name) # this loop may never end
# βœ… Good: build a separate new list
greetings = []
for name in names:
greetings.append(f"Hi {name}!")
  • Tracking the index by hand when enumerate() would do it for you. It works, but it is more code and easy to get wrong.

βœ… Best Practices

Small habits that keep these loops clean.

  • Set your starting value on its own line, right before the loop, so it is easy to see.
  • Give the accumulator a clear name. total, count, highest tell the reader the job at a glance. That is much better than x.
  • Reach for the built-ins sum(), max(), min() when the rule is simple. Write the manual loop when you need a custom condition.
  • Use enumerate() any time you need the position. It is cleaner and harder to get wrong than a hand-rolled counter.

🧩 What You’ve Learned

βœ… A loop pattern is a reusable shape for a common job, so you stop reinventing loops.

βœ… Running a total uses an accumulator that starts at 0 and adds each item.

βœ… Counting adds 1 for each item that passes a test, not the value itself.

βœ… Finding a max or min starts the guess at the first item, then updates when something beats it.

βœ… Building a new list starts empty and uses append() on every turn.

βœ… enumerate() gives you the index and the value together, and can start counting from any number.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    In a running-total loop, where should `total = 0` go?

    Why: The starting value must be set once before the loop, or it resets to zero on every turn and you lose the total.

  2. 2

    What is the key difference between a summing loop and a counting loop?

    Why: A sum adds each value itself, while a count adds 1 for every item that matches the condition.

  3. 3

    Why is `highest = 0` a risky starting value when finding a maximum?

    Why: If all values are below zero, 0 beats them all and you get the wrong answer, so start from the first real item.

  4. 4

    What does `enumerate(tasks)` give you on each turn of the loop?

    Why: enumerate() hands back both the position (index) and the item, so you can unpack them into two variables.

πŸš€ What’s Next?

You can now make a loop do almost any everyday job. Next we package code into reusable blocks you can call by name. That is the idea behind functions.

Introduction to Functions

Share & Connect