Published on : Apr 06, 2026

What is Loop?

The Complete Guide to Loops: From Basic Syntax to Real-World Algorithms

8 Minutes Read
Gradient

Asish Gambhir

Engineering Lead at Winzo Winzo

what is loop

Why Every Programmer Needs to Master Loops

2.png

Imagine you’re building an app that sends a daily reminder notification to 5 million users. Would you write the notification code 5,000,000 times? Obviously not. Would you write it even 10 times? No. You’d write it once and let a loop handle the rest.

Now think bigger. Every search engine that crawls billions of web pages, every social media feed that loads post after post, every game that renders 60 frames per second , all of it runs on loops. Loops are not just a beginner concept you learn and move past. They are the engine of all computation.

Yet most beginners treat loops as a simple trick, “oh just use for i in range(10)” , without ever understanding why they work, how the computer actually processes them, or which type of loop to reach for in a given situation.

This blog fixes that. We’ll go from the very basics all the way to how loops work at the CPU level, the algorithm patterns built on top of them, and the subtle mistakes even experienced developers make.


What is a Loop?

A loop is a programming construct that executes a block of code repeatedly as long as a specified condition remains true, or for a fixed number of times.

Break that definition apart:

  • Executes repeatedly: The same lines of code run multiple times, not just once.

  • A block of code: It can be one line or a hundred lines; the loop wraps all of it

  • As long as a condition is true: There’s always a governing rule that decides when to stop

  • Or for a fixed number of time: In some loops, you specify upfront exactly how many iterations to run

Key Analogy: Think of a loop like a conveyor belt in a factory. The same operation (add a label, tighten a bolt, package a box) is performed on every item that passes through , automatically, repeatedly , until the belt is told to stop. You write the operation once; the belt handles the repetition.

Visualising a Simple Loop

Let’s say we want to print every player’s score in a game:

scores = [85, 92, 78, 95, 88]

Without a loop, you’d write:

print(scores[0]) print(scores[1]) print(scores[2]) print(scores[3]) print(scores[4])

With a loop:

for score in scores: print(score)

Same result. Five times fewer lines. And if the list grows to 5,000 players, the loop still works , the manual version breaks entirely.

Creating a Basic Loop

# Print "Hello" five times
for i in range(5):
    print("Hello")

How Loops Work Under the Hood

This is the section most tutorials skip , and it’s the key to understanding why loops behave the way they do, and why some loops are faster than others.

When your code runs, it gets converted into machine instructions that the CPU executes one by one. At the machine level, a loop is just:

  1. A block of instructions to execute

  2. A conditional jump instruction that says: “If the condition is still true, go back to the start of the block”

The Program Counter and the Jump

Every CPU has a register called the Program Counter (PC) , it holds the memory address of the next instruction to execute. Normally, after each instruction, the PC moves forward by one step.

A loop works by inserting a jump instruction at the end of the loop body. If the loop condition is still true, the jump sends the PC backwards to the start of the loop body. This is how the repetition happens at the hardware level.

Instruction 10: LOAD score from memory

Instruction 11: PRINT score

Instruction 12: INCREMENT counter

Instruction 13: COMPARE counter to 5

Instruction 14: JUMP to Instruction 10 if counter < 5 ← the loop

Instruction 15: (next code after the loop)

Why Loop Performance Matters: Branch Prediction

Modern CPUs are deeply pipelined , they start executing the next instruction before the current one finishes. But at a conditional jump (like the end of a loop), the CPU doesn’t yet know whether to jump back or continue forward. So it guesses , this is called branch prediction.

For a loop that runs 1,000 times, the CPU correctly predicts “jump back” 999 times and “don’t jump” once. This prediction accuracy is extremely high, making loops very efficient in practice.

Performance Insight: A well-structured loop over a contiguous data structure (like an array) is one of the fastest possible operations in programming , the CPU’s branch predictor and cache work together to execute it at near-maximum speed.


Types of Loops

Loops are categorised in two ways: by when they check their condition and by how they determine when to stop.

By Condition Check Timing

Type

Checks Condition

Guaranteed to Run At Least Once?

while

Before the body

No , body may never run

for

Before the body

No , body may never run

do-while

After the body

Yes , always runs at least once

By How They Count

Loop Type

Best Used When

while

You don’t know how many iterations you need

for

You know the exact number of iterations upfront

for-each

You want to visit every item in a collection

do-while

You need the loop body to run at least once before checking

infinite

You need to run forever (until a breakanually)


The While Loop: Deep Dive

A while loop is an entry-controlled loop , it evaluates its condition before running the body. If the condition is false from the very beginning, the loop body never executes at all.

image (4).png

The while loop is best when you don’t know in advance how many iterations are needed , the loop keeps going as long as “something is true”.

Syntax:

while condition:
    # loop body

How it Works , Step by Step

  1. Evaluate the condition

  2. If true → execute the loop body, then return to step 1

  3. If false → skip the loop entirely and move to the next line after the loop

Code Example , User Input Validation

password = ""

while password != "secret123":
    password = input("Enter password: ")

print("Access granted!")

This loop doesn’t know how many attempts the user will need , it keeps asking until they get it right. That uncertainty makes while the right choice.

import random

count = 0
dice = 0

while dice != 6:
    dice = random.randint(1, 6)
    count += 1

print(f"Rolled{count} time(s) to get a 6")

The Infinite While Loop

A while loop with the condition set to true runs forever , until a break statement exits it manually. This pattern is common in servers, games, and event loops.

# Server listening loop , runs until manually stopped
while True:
    request = listen_for_request()
    if request == "shutdown":
        break
    handle(request)

Note: If you forget to update the variable involved in the condition, or if the condition can never become false, you’ll create an unintentional infinite loop , the program will hang and consume 100% CPU. Always ensure your while condition can eventually become false.

The For Loop: Deep Dive

A for loop is also an entry-controlled loop, but it’s designed specifically for situations where you know exactly how many times the code should run. It packages the counter setup, condition check, and counter update into one clean line.

image (8).png

Syntax (JavaScript / Java / C++):

for (initialisation; condition; update) {
    // loop body
}

Each part: - Initialisation , runs once before the loop starts (e.g., let i = 0) - Condition , checked before every iteration; loop stops when false - Update , runs at the end of every iteration (e.g., i++)

for i in range(start, stop, step):
    # loop body

Code Example , Printing a Multiplication Table

n = 7

for i in range(1, 11):
    print(f"{n} x{i} ={n * i}")

Output:

7 x 1 = 7
7 x 2 = 14
7 x 3 = 21
...
7 x 10 = 70
const n = 7;

for (let i = 1; i <= 10; i++) {
    console.log(`${n} x${i} =${n * i}`);
}

Counting Backwards

A for loop can count in any direction , just adjust the initialisation, condition, and update.

# Countdown from 10 to 1
for i in range(10, 0, -1):
    print(i)
print("Liftoff! 🚀")

Counting in Steps

# Print every even number from 0 to 20
for i in range(0, 21, 2):
    print(i)

Note: The counter variable is conventionally named i, j, or k , borrowed from mathematics. In complex loops, use descriptive names like row_index or player_count for clarity.

The For-Each Loop: Deep Dive

A for-each loop (also called an enhanced for loop or iterator loop) is designed to visit every element in a collection , list, array, set, dictionary, string , without managing a counter variable at all. You just say “do this for each item.”

image (5).png

It’s the cleanest, most readable way to iterate when you need every element and don’t need the index.

for item in collection:
    # use item

Iterating Different Collection Types

# List
fruits = ['banana', 'apple', 'orange']
for fruit in fruits:
    print(fruit)

# String (character by character)
for char in "Hello":
    print(char)

# Dictionary (keys)
scores = {'Alice': 95, 'Bob': 87, 'Carol': 92}
for name in scores:
    print(f"{name}:{scores[name]}")

# Dictionary (key + value together)
for name, score in scores.items():
    print(f"{name} scored{score}")

# Set
unique_tags = {'python', 'coding', 'loops'}
for tag in unique_tags:
    print(tag)

When You Need the Index Too

If you need both the element and its position, use enumerate() in Python or a regular for with an index:

fruits = ['banana', 'apple', 'orange']

# Python , enumerate gives index + value
for i, fruit in enumerate(fruits):
    print(f"Position{i}:{fruit}")

The Do-While Loop: Deep Dive

A do-while loop is an exit-controlled loop , it runs the body first, and checks the condition after. This is the key difference from all other loops.

image (6).png

The guarantee: The loop body always executes at least once, regardless of whether the condition is true or false.

Syntax (JavaScript / Java / C++):

do {
    // loop body , always runs at least once
} while (condition);

When Does This Matter?

Consider a menu-driven program. You always want to show the menu before asking if the user wants to continue , not after:

No JavaScript code yet.

Without do-while, you’d have to show the menu once before the loop and then again inside , duplicating code.

Full Code Example , PIN Entry System

const correctPin = 1234;
let attempts = 0;
let enteredPin;

do {
    enteredPin = parseInt(prompt("Enter your PIN:"));
    attempts++;

    if (enteredPin !== correctPin) {
        console.log("Wrong PIN. Try again.");
    }
} while (enteredPin !== correctPin && attempts < 3);

if (enteredPin === correctPin) {
    console.log("Access granted!");
} else {
    console.log("Account locked after 3 failed attempts.");
}

⚠️ Python Note: Python does not have a native do-while loop. Simulate it with while True and a break:

Nested Loops

What is it?

A nested loop is a loop placed entirely inside another loop. The inner loop completes all its iterations for every single iteration of the outer loop.

image (7).png

If the outer loop runs m times and the inner loop runs n times, the total iterations are m × n.

[ Insert image: Nested loop visualization , outer loop box containing inner loop box, with a counter showing total iterations = m × n ]

Code Example , Multiplication Table Grid

for i in range(1, 6):
    for j in range(1, 6):
        print(f"{i * j:4}", end="")
    print()  # new line after each row

Output:

1 2 3 4 5

2 4 6 8 10

3 6 9 12 15

4 8 12 16 20

5 10 15 20 25

for (let i = 1; i <= 5; i++) {
    let row = "";
    for (let j = 1; j <= 5; j++) {
        row += String(i * j).padStart(4);
    }
    console.log(row);
}

Nested Loop with 2D Array , Processing a Grid

grid = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

for row in grid:
    for cell in row:
        print(cell, end=" ")
    print()

Output:

1 2 3

4 5 6

7 8 9

Pattern Printing with Nested Loops:

# Right triangle
for i in range(1, 6):
    for j in range(i):
        print("*", end=" ")
    print()

Output:

*

* *

* * *

* * * *

* * * * *

💡 Tip: You can nest any loop type inside any other , for inside while, while inside for, even do-while inside for. The types don’t have to match.

⚠️ Performance Warning: Triple or quadruple nested loops (O(n³) or O(n⁴) complexity) get extremely slow with large inputs. Always think about whether nesting can be avoided.

Loop Control Statements

Loop control statements let you alter the default flow of a loop mid-execution , skipping iterations, exiting early, or doing nothing at all.

Time Complexity Overview of Control Statements

Statement

Effect

Changes Loop Count?

break

Exits the loop immediately

Yes , terminates early

continue

Skips the rest of the current iteration

Yes , skips some iterations

pass

Does absolutely nothing

No

return (i     

Exits the loop AND the function

Yes

1. break , Exit the Loop Immediately

When break is hit the loop stops right away. The program jumps to the first line after the loop.

numbers = [3, 7, 2, 9, 5, 1, 8]

for num in numbers:
    if num == 9:
        print("Found 9! Stopping search.")
        break
    print(num)

Output:

3

7

2

Found 9! Stopping search.

const numbers = [3, 7, 2, 9, 5, 1, 8];

for (const num of numbers) {
    if (num === 9) {
        console.log("Found 9! Stopping search.");
        break;
    }
    console.log(num);
}

Real-world analogy: You’re searching through a filing cabinet for a document. The moment you find it, you stop , you don’t go through every remaining file.

2. continue , Skip the Current Iteration

continue skips everything after it in the current iteration and jumps straight to the next one. The loop itself doesn’t stop.

# Print only odd numbers
for i in range(1, 11):
    if i % 2 == 0:
        continue   # skip even numbers
    print(i)

Output:

1

3

5

7

9

for (let i = 1; i <= 10; i++) {
    if (i % 2 === 0) continue;
    console.log(i);
}

Real-world analogy: A quality control inspector on a production line , when they spot a defective item, they push it aside and keep checking the rest. They don’t shut down the whole line.

3. pass , Do Nothing (Placeholder)

passis unique to Python. It’s a no-operation statement , it does literally nota placeholder when Python’s syntax requires a code block, but you haven’t written the logic yet.

for item in large_dataset:
    pass  #TODO: add processing logic here

# Also used for empty function/class definitions
def process_data():
    pass   # Will implement later

break in Nested Loops

An important detail: break only exits the innermost loop it’s inside. The outer loop continues.

for i in range(3):
    for j in range(3):
        if j == 1:
            break         # only exits the inner loop
        print(f"i={i}, j={j}")

Output:

i=0, j=0

i=1, j=0

i=2, j=0

Loops Across Programming Languages

Feature

Python

JavaScript

Java

C/C++

whileloop

✅ Yes

✅ Yes

✅ Yes

✅ Yes

for loop

✅ Yes (range-based)

✅ Yes

✅ Yes

✅ Yes

for-each

for x in list

for...of

✅ Enhanced for

✅ Range-based (C++11)

do-while

❌ Not built-in

✅ Yes

✅ Yes

✅ Yes

break

✅ Yes

✅ Yes

✅ Yes

✅ Yes

continue

✅ Yes

✅ Yes

✅ Yes

✅ Yes

pass

✅ Yes

❌ No

❌ No

❌ No

Labeled break

❌ No

✅ Yes

✅ Yes

❌ No

Infinite loop

while True:

while(true){}

while(true){}

while(1){}

Loop variable scope

Function-scoped

Block-scoped (let)

Block-scoped

Block-scoped

List comprehension

[x for x in list]

❌ (use .map())

❌ (use streams)

❌ No

Labeled Break (Java / JavaScript only)

In Java and JavaScript, you can label an outer loop and break out of it directly from inside a nested loop:

outer:
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        if (j == 1) break outer;  // exits the outer loop entirely
        System.out.println("i=" + i + " j=" + j);
    }
}

Output:

i=0 j=0

Loops vs Recursion

Both loops and recursion solve repetition problems , but they work differently and suit different situations.

Feature

Loop

Recursion

How it works

Iterates using a counter or condition

Function calls itself

Memory usage

Low , uses a fixed amount of stack space

Higher , each call adds a stack frame

Performance

Generally faster

Slower due to function call overhead

Risk

Infinite loops

Stack overflow

Best for

Sequential, iterative tasks

Hierarchical or divide-and-conquer problems

Readability

More readable for simple repetition

More elegant for tree traversal, fractals

Tail call optimization

N/A

Some languages optimize this

Same problem , two approaches:

# Loop , sum of numbers 1 to n
def sum_loop(n):
    total = 0
    for i in range(1, n + 1):
        total += i
    return total

# Recursion , same result
def sum_recursive(n):
    if n == 0:
        return 0
    return n + sum_recursive(n - 1)

print(sum_loop(100))       # 5050
print(sum_recursive(100))  # 5050

💡 Rule of thumb: Default to loops for repetitive tasks. Use recursion when the problem is naturally hierarchical (e.g., folder trees, parsing HTML, maze solving).

Real-World Use Cases of Loops

Loops aren’t just a textbook concept. They are baked into every piece of software you use daily.

Game Engines , The Game Loop

Every game runs a while True loop called the game loop , it endlessly updates game state and redraws the screen, typically 60 times per second.

while game_is_running:
    handle_input()
    update_game_state()
    render_frame()
    wait_for_next_frame()0

Web Servers , Request Handling

A web server loops infinitely, waiting for incoming HTTP requests. For each request, it processes it and sends a response , then goes back to listening.

Data Processing , ETL Pipelines

When a company processes millions of customer records nightly, it runs loops , reading each row, transforming it, and writing it to a new database. These loops process terabytes of data while you sleep.

for epoch in range(100):           # outer: 100 training passes
    for batch in training_data:    # inner: process each batch
        predictions = model(batch)
        loss = compute_loss(predictions)
        update_weights(loss)

Every neural network trains by looping through the training data many times. Each full pass through the data is called an epoch.

Image Processing , Pixel Manipulation

A photo filter works by looping over every pixel in an image (a 2D array of values) and applying a transformation to each one.

for row in image:
    for pixel in row:
        pixel.brightness += 20   # brighten every pixel

Advanced Concepts & Algorithm Patterns

How Python’s range() Works Internally

range() doesn’t create a list in memory , it’s a lazy iterator. It generates values one at a time, on demand, using a simple formula: value = start + (step × index). This means range(1_000_000) uses the same tiny amount of memory as range(10).

# This uses barely any memory despite 1 million iterations
for i in range(1_000_000):
    process(i)

# Contrast with , THIS creates a list of 1 million integers in memory
for i in list(range(1_000_000)):  # wasteful
    process(i)

Loop Unrolling , Why Compilers Optimise Loops

Modern compilers sometimes convert:

for i in range(4):
    arr[i] *= 2

into the equivalent of:

arr[0] *= 2
arr[1] *= 2
arr[2] *= 2
arr[3] *= 2

This is called loop unrolling , eliminating the overhead of the condition check and counter update. You don’t do this manually, but understanding it explains why tight loops run faster than you might expect.

The Sliding Window Technique

One of the most powerful loop-based algorithm patterns. Instead of recomputing a result from scratch for every sub-sequence, you maintain a “window” and slide it across the data , adding the new element and removing the old one each step.

Problem: Find the maximum sum of any 3 consecutive numbers in an array.

Naïve approach , O(n²):

def max_sum_naive(arr, k):
    max_sum = 0
    for i in range(len(arr) - k + 1):
        window_sum = sum(arr[i:i+k])   # recomputes sum from scratch each time
        max_sum = max(max_sum, window_sum)
    return max_sum

Sliding Window , O(n):

def max_sum_sliding(arr, k):
    window_sum = sum(arr[:k])   # compute first window once
    max_sum = window_sum

    for i in range(k, len(arr)):
        window_sum += arr[i] - arr[i - k]   # slide: add new, remove old
        max_sum = max(max_sum, window_sum)

    return max_sum

print(max_sum_sliding([2, 1, 5, 1, 3, 2], 3))  # Output: 9  (5+1+3)

The Two-Pointer Technique

Two variables act as pointers that start at opposite ends of a sorted array and move toward each other. Eliminates the need for a nested loop in many problems , O(n) instead of O(n²).

Problem: Check if any two numbers in a sorted array add up to a target.

def two_sum(arr, target):
    left, right = 0, len(arr) - 1

    while left < right:
        current = arr[left] + arr[right]
        if current == target:
            return (left, right)
        elif current < target:
            left += 1    # need bigger sum , move left pointer right
        else:
            right -= 1   # need smaller sum , move right pointer left

    return None

print(two_sum([1, 3, 5, 7, 9], 12))  # Output: (2, 4) → 5 + 7 ... wait → (1, 4) → 3+9=12 ✓

Loop Invariants , Writing Correct Loops

A loop invariant is a condition that is true before the loop starts, remains true after every iteration, and guarantees correctness when the loop ends. Thinking about invariants is how experienced developers write bug-free loops.

# Invariant: after each iteration, arr[0..i-1] contains the i smallest elements in sorted order
arr = [64, 34, 25, 12, 22, 11, 90]

for i in range(len(arr)):
    min_idx = i
    for j in range(i + 1, len(arr)):
        if arr[j] < arr[min_idx]:
            min_idx = j
    arr[i], arr[min_idx] = arr[min_idx], arr[i]  # swap smallest into position

print(arr)  # [11, 12, 22, 25, 34, 64, 90]

Advantages & Disadvantages

✅ Advantages of Using Loops

  • Eliminate code duplication , write once, execute many times

  • Handle dynamic data , process collections of any size without changing the code

  • Enable automation , automate repetitive tasks that would be impossible to do manually

  • Pair with data structures , essential for working with arrays, lists, trees, and graphs

  • Power algorithms , sorting, searching, pattern matching all rely on loops

  • Scalable , the same for loop that processes 10 records handles 10 million records

❌ Disadvantages and Risks

  • Infinite loops , a missing update or wrong condition hangs the program

  • Off-by-one errors , subtle boundary mistakes are one of the most common bugs in all of programming

  • Performance pitfalls , deeply nested loops can be catastrophically slow on large data (O(n³) and beyond)

  • Readability , complex nested loops with break and continue can be very hard to follow

  • Modifying data while iterating , can cause skipped elements or crashes

  • Stack overflow risk (in recursive loops) , not directly loops, but interchangeable patterns can cause issues


Conclusion

Loops are deceptively simple on the surface, but surprisingly deep once you understand how they actually work. Let’s recap what we covered:

  • A loop is a block of code that repeats as long as a condition is true, powered by a CPU-level conditional jump instruction.

  • The while loop is entry-controlled and best for unknown iteration counts.

  • The for loop is entry-controlled with a built-in counter and best for known iteration counts.

  • The for-each loop cleanly iterates every element in a collection without a counter.

  • The do-while loop is exit-controlled and guarantees at least one execution.

  • Nested loops multiply iterations and power grid-based and pattern problems.

  • break, continue, and pass give you fine-grained control over loop flow.

  • Different languages handle loops slightly differently , Python lacks do-while, Java/JS support labeled breaks.

  • Loops and recursion both solve repetition , loops are faster, recursion is more elegant for hierarchical problems.

  • Advanced patterns like sliding window and two-pointer use loops to solve problems in O(n) that naïve approaches solve in O(n²).

Loops are the foundation on which algorithms are built. Mastering them , truly mastering them, not just knowing the syntax , is the gateway to understanding sorting, searching, data processing, machine learning, and almost every other topic in computer science.

FAQ

FREQUENTLY ASKED QUESTIONS

A `while` loop checks a condition and keeps running as long as it’s true , best used when you don’t know in advance how many iterations you’ll need. A `for` loop has a built-in counter and runs for a specific, predetermined number of iterations. If you know the count, use `for`. If you don’t, use `while`.
Python’s design philosophy prioritises simplicity and readability. The language designers felt that while True: ... if condition: break is clear enough and avoids the confusion that do-while causes for beginners (who often struggle to remember that the body runs before the check). It’s a deliberate choice, not an oversight.
An infinite loop runs forever because its exit condition never becomes false. Common causes: forgetting to increment the counter (`i += 1`), using the wrong comparison operator, or a condition that can never be satisfied. Prevention: always trace through your loop manually to confirm the condition will eventually be false. Use `break` statements as a safety mechanism in complex cases.
An off-by-one error is when your loop runs one iteration too many or too few. For example, `range(10)` gives 0–9 (10 values), but `range(1, 10)` gives 1–9 (9 values). This is one of the most common bugs in all of programming. Always verify your loop’s start, end, and boundary conditions carefully.
In Python, a plain break only exits the innermost loop. To exit multiple loops, common solutions are: (1) wrap the nested loops in a function and use return, (2) use a boolean flag variable, or (3) in Java/JavaScript, use labeled break to specify exactly which loop to exit.
break completely terminates the loop , no more iterations happen. continue skips the rest of the current iteration only and moves on to the next one. Think of break as “stop the whole conveyor belt” and continue as “skip this item but keep the belt running.
Use a loop for straightforward, sequential repetition , counting, iterating lists, accumulating values. Use recursion when the problem has a naturally hierarchical or self-similar structure , traversing folder trees, parsing nested HTML, solving mazes, or implementing divide-and-conquer algorithms like merge sort. Loops are generally faster; recursion is often more elegant for tree-shaped problems.
Time complexity describes how the number of operations in your code grows as the input size grows. A single loop over n items is O(n) , double the input, double the time. A nested loop over n items is O(n²) , double the input, quadruple the time. A triple nested loop is O(n³). Understanding this helps you write loops that scale , a solution that works on 100 items might be unusably slow on 1,000,000 if it has O(n²) or worse complexity.