How to loop in Python

Master Python loops. This guide covers different methods, tips, real-world examples, and debugging common errors.

How to loop in Python
Published on: 
Thu
Feb 12, 2026
Updated on: 
Mon
Apr 13, 2026
The Replit Team

Loops are a fundamental Python concept. They let you automate repetitive tasks and process data collections efficiently. To master Python, you must first master its loops.

In this article, we'll cover essential loop techniques and practical tips. You'll see real-world applications and learn to debug common issues, which will help you construct powerful loops with confidence.

Using the basic for loop

for i in range(5):
print(i)--OUTPUT--0
1
2
3
4

The basic for loop is Python's standard for iterating over a sequence. The key here is the range(5) function. It creates an iterable object that produces numbers from 0 up to (but not including) 5 on demand. This approach is highly efficient, especially for large ranges, as it doesn't store the entire sequence in memory.

The loop repeats a simple process until the sequence is exhausted:

  • It requests the next number from the range object.
  • It assigns that number to the variable i.
  • It executes the indented code block—in this case, print(i).

Common looping techniques

Beyond the basic for loop, you'll find several other techniques for controlling iteration and working with data, from while loops to elegant list comprehensions.

Using the while loop

count = 0
while count < 5:
print(count)
count += 1--OUTPUT--0
1
2
3
4

A while loop is condition-driven, executing a block of code as long as an expression—here, count < 5—remains true. This makes it ideal for situations where the number of iterations isn't known in advance.

  • The condition is checked at the start of every pass.
  • It's essential to update the variable being tested, for example, with count += 1.
  • Without an update, the condition never changes, and you'll get stuck in an infinite loop.

Looping through data structures

fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)--OUTPUT--apple
banana
cherry

The for loop is perfect for iterating directly over data structures like lists. Instead of generating numbers with range(), the loop pulls each element from the fruits list one by one until the sequence is exhausted.

  • On the first pass, fruit is "apple".
  • On the second, it becomes "banana", and finally "cherry".

This approach is clean and highly readable because you work with the elements themselves, not their index positions. This is the standard pattern for iterating through a list in Python.

Using list comprehensions

numbers = [1, 2, 3, 4, 5]
squared = [x**2 for x in numbers]
print(squared)--OUTPUT--[1, 4, 9, 16, 25]

List comprehensions offer a compact and readable way to create new lists from existing ones. They let you combine a loop and an expression into a single, elegant line. In the example, [x**2 for x in numbers] builds the new squared list.

  • The for x in numbers part works just like a standard loop, iterating through each item.
  • The x**2 expression is the operation performed on every item x.
  • The results are automatically collected into a new list.

This approach is often more efficient and Pythonic than using a traditional for loop with append().

Advanced looping techniques

Once you've mastered the basics, you can tackle more complex iteration challenges with powerful built-in functions like enumerate(), zip(), and the itertools module.

Using enumerate() to access index and value

fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits):
print(f"Index {index}: {fruit}")--OUTPUT--Index 0: apple
Index 1: banana
Index 2: cherry

The enumerate() function is your go-to when you need both an item and its position in a sequence. It simplifies the common pattern of needing an index while looping, making your code cleaner and more readable than managing a counter manually. Learn more about using enumerate in Python.

  • It wraps an iterable and generates pairs—a count (starting from zero by default) and the value from the iterable.
  • In the loop, for index, fruit in enumerate(fruits), each pair is automatically unpacked into the two variables, giving you direct access to both.

Using zip() to iterate through multiple sequences

names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
for name, age in zip(names, ages):
print(f"{name} is {age} years old")--OUTPUT--Alice is 25 years old
Bob is 30 years old
Charlie is 35 years old

The zip() function is a powerful tool for iterating over multiple sequences in parallel. It pairs corresponding elements from each list, allowing you to process them together in a single loop.

  • It works by creating an iterator that aggregates elements from each of the iterables. In each pass, it yields a tuple—like ("Alice", 25)—which is then unpacked into the variables name and age.
  • The iteration stops as soon as the shortest input sequence is exhausted. This means if one list were longer than the other, its extra items would simply be ignored.

Using itertools for complex iteration patterns

import itertools
for item in itertools.chain([1, 2], ['a', 'b']):
print(item)--OUTPUT--1
2
a
b

The itertools module is a powerhouse for handling complex iteration tasks efficiently. It offers a collection of fast, memory-efficient tools for creating custom loop patterns. In this example, itertools.chain() is used to seamlessly link multiple sequences.

  • The function takes two or more iterables and treats them as a single, continuous sequence.
  • It processes all items from the first list, [1, 2], before moving on to the second, ['a', 'b'].
  • This is far more memory-efficient than manually concatenating lists, especially when dealing with large datasets.

Move faster with Replit

Replit is an AI-powered development platform that comes with all Python dependencies pre-installed, so you can skip setup and start coding instantly. You can go from learning loop techniques to building complete applications faster.

With Agent 4, you can describe the app you want to build, and it will handle the implementation. Instead of piecing together code, you can focus on the final product. For example, Agent can create:

  • A sales report generator that combines product names and sales figures from separate lists into a single summary.
  • A simple playlist tool that automatically numbers a list of your favorite tracks.
  • A data cleaning utility that filters a raw dataset, like pulling all positive values from a list of numbers and squaring them.

Simply describe your app, and Replit will write the code, test it, and fix issues automatically, all within your browser.

Common errors and challenges

Even experienced developers run into loop-related issues; here’s how you can navigate some of the most common pitfalls.

  • Fixing infinite while loops: An infinite loop is a classic trap where a while loop's condition never becomes false, causing it to run forever. This usually happens when you forget to update the variable being tested inside the loop. To fix it, just make sure your loop's body contains logic—like incrementing a counter—that gives it a clear exit path.
  • Safely modifying a list during iteration: It's a bad idea to change a list while you're looping over it, as this can cause the loop to skip items or behave erratically. The safest approach is to iterate over a copy. You can create one with slice notation (for item in my_list[:]), which lets you modify the original my_list without confusing the loop's iterator.
  • Fixing off-by-one errors in range(): This classic bug causes your loop to run one time too many or one time too few. It often happens because it's easy to forget that range(5) produces numbers from 0 to 4, not including 5. If you need to count from 1 to 5, you'd use range(1, 6). Always double-check your start and stop values to make sure your loop covers the exact sequence you intend.

Fixing infinite while loops

A while loop becomes infinite when its controlling condition never evaluates to false, trapping your program in a cycle. It's a common mistake that usually stems from forgetting to update the state that the condition checks. See what this looks like below.

counter = 0
while counter < 5:
print(counter)
# Forgot to increment counter

Because the counter variable is never updated, its value remains 0. The condition counter < 5 is always true, so the loop runs forever. The corrected code below shows how to fix this with a small addition.

counter = 0
while counter < 5:
print(counter)
counter += 1

By adding counter += 1, you ensure the loop makes progress toward its exit condition. Each pass increases the counter's value, so after five iterations, the condition counter < 5 becomes false, and the loop stops as intended. This is a crucial step to remember in any while loop where the exit depends on a state that must change over time. For more techniques on ending a while loop, check our detailed guide.

Safely modifying a list during iteration

Safely modifying a list during iteration

Modifying a list while iterating over it can cause unpredictable behavior. When you use a method like remove() inside the loop, the list shrinks, but the iterator advances as if it didn't. This desynchronization often makes the loop skip elements. The code below demonstrates this pitfall.

numbers = [1, 2, 3, 4, 5]
for num in numbers:
if num % 2 == 0:
numbers.remove(num)
print(numbers)

The problem occurs when 2 is removed. The list shrinks, and 3 shifts into the second position. Because the iterator has already processed that position, it moves on, skipping 3 entirely. See the corrected approach below.

numbers = [1, 2, 3, 4, 5]
odd_numbers = [num for num in numbers if num % 2 != 0]
print(odd_numbers)

The solution uses a list comprehension to build a new list containing only the desired elements. Instead of removing items, [num for num in numbers if num % 2 != 0] creates a fresh list, odd_numbers, with just the odd numbers. This approach is safer and more readable because it avoids modifying the list you're currently looping over, preventing unexpected skips. It's the recommended way for filtering a list in Python.

Fixing off-by-one errors in range()

An off-by-one error is a frequent issue where a loop runs one time too many or too few. It's especially common with range() because the function stops before reaching the specified end number, which can be counterintuitive.

The following code attempts to print numbers from one to five, but it misses the mark because of this exact behavior.

for i in range(1, 5):
print(i)

This loop prints 1, 2, 3, and 4, stopping just short of 5. Since the range() function excludes the end value, the count is off by one. The corrected code below shows the simple fix.

for i in range(1, 6):
print(i)

By changing the loop to range(1, 6), you include the number 5. That's because the range() function generates numbers up to, but not including, its stop value. To get the correct count, you simply extend the range by one. Keep an eye on this whenever your loop's boundaries are critical, like when working with data indices or generating numbered lists where the final number matters. For comprehensive details about using range in Python, explore our dedicated guide.

Real-world applications

Beyond fixing bugs, loops are the engine for solving real-world challenges, from processing files in bulk to modeling complex systems. These patterns are perfect for vibe coding when you need to quickly prototype solutions.

Batch processing files with for loops

A for loop is a natural fit for batch processing, letting you iterate through a collection of files and apply specific logic to each one.

files = ["data.txt", "report.csv", "image.jpg", "notes.txt"]
txt_count = 0
csv_count = 0

for filename in files:
if filename.endswith('.txt'):
print(f"Processing text file: {filename}")
txt_count += 1
elif filename.endswith('.csv'):
print(f"Processing CSV file: {filename}")
csv_count += 1

print(f"Processed {txt_count} text files and {csv_count} CSV files")

This code snippet shows a practical way to sort and count data within a list. The loop examines each filename and uses conditional checks to categorize it. This pattern is highly effective for selectively processing items from a larger collection.

  • The endswith() string method is key here, efficiently checking if a filename ends with a specific extension like .txt or .csv.
  • Counters like txt_count and csv_count are updated only when a condition is met.
  • Files that don't match any condition, such as image.jpg, are simply skipped, keeping the logic clean and focused.

Simulating population growth with while loops

Because a while loop continues until a condition is met, it's the perfect tool for modeling processes with an unknown endpoint, like population growth.

initial_population = 1000
growth_rate = 0.05
target = 2000
years = 0
population = initial_population

while population < target:
population *= (1 + growth_rate)
years += 1

print(f"Starting population: {initial_population}")
print(f"Growth rate: {growth_rate*100}% per year")
print(f"It takes {years} years to reach {target}")

This simulation calculates the time needed for a population to hit a specific target. The while loop is the core of the model, repeatedly applying a growth formula until the population variable surpasses the target.

  • Inside the loop, the population is updated using compound growth with population *= (1 + growth_rate).
  • The years variable is incremented in each pass, tracking the elapsed time.

This structure effectively models a process over time, stopping only when the desired outcome is achieved.

Get started with Replit

Now, turn your knowledge into a real tool. With Replit Agent, you can describe what you want to build, like “a script that zips a list of products with their prices” or “a tool that batch renames files in a folder.”

Replit Agent will write the code, test for errors, and deploy your app for you. Start building with Replit.

Build your first app today

Describe what you want to build, and Replit Agent writes the code, handles the infrastructure, and ships it live. Go from idea to real product, all in your browser.

Build your first app today

Describe what you want to build, and Replit Agent writes the code, handles the infrastructure, and ships it live. Go from idea to real product, all in your browser.