Looping Techniques
Programming
Indexing
Reverse Looping
Iteration

Loop backwards using indices

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Looping backwards using indices means iterating from the last element to the first by decrementing an index variable. This is useful when removing elements during iteration (to avoid index shifting), processing data in reverse order, or implementing algorithms like reverse string comparison. Every major language supports backward loops through for loops with decrementing counters, and many provide built-in utilities like Python's reversed() or JavaScript's Array.reverse().

Python

Using range() with Negative Step

python
1items = ['a', 'b', 'c', 'd', 'e']
2
3# range(start, stop, step) — stop is exclusive
4for i in range(len(items) - 1, -1, -1):
5    print(f"Index {i}: {items[i]}")
6# Index 4: e
7# Index 3: d
8# Index 2: c
9# Index 1: b
10# Index 0: a

range(4, -1, -1) generates 4, 3, 2, 1, 0. The stop value -1 is exclusive, so it stops after 0.

Using reversed()

python
1# reversed() with enumerate for index + value
2for i, item in enumerate(reversed(items)):
3    original_index = len(items) - 1 - i
4    print(f"Index {original_index}: {item}")
5
6# Simpler: reversed(range(...))
7for i in reversed(range(len(items))):
8    print(f"Index {i}: {items[i]}")

Safe Removal During Backward Iteration

python
1numbers = [1, 2, 3, 4, 5, 6, 7, 8]
2
3# Remove even numbers — backward loop avoids index shifting
4for i in range(len(numbers) - 1, -1, -1):
5    if numbers[i] % 2 == 0:
6        del numbers[i]
7
8print(numbers)  # [1, 3, 5, 7]

Removing elements during a forward loop skips elements because indices shift. Backward iteration avoids this because removing an element only affects indices after the current position.

JavaScript

for Loop

javascript
1const items = ['a', 'b', 'c', 'd', 'e'];
2
3for (let i = items.length - 1; i >= 0; i--) {
4    console.log(`Index ${i}: ${items[i]}`);
5}
6// Index 4: e
7// Index 3: d
8// ...

Safe Removal with splice()

javascript
1const numbers = [1, 2, 3, 4, 5, 6, 7, 8];
2
3for (let i = numbers.length - 1; i >= 0; i--) {
4    if (numbers[i] % 2 === 0) {
5        numbers.splice(i, 1);
6    }
7}
8console.log(numbers); // [1, 3, 5, 7]

Java

java
1int[] items = {10, 20, 30, 40, 50};
2
3for (int i = items.length - 1; i >= 0; i--) {
4    System.out.println("Index " + i + ": " + items[i]);
5}

ArrayList Backward Removal

java
1import java.util.ArrayList;
2import java.util.List;
3
4List<Integer> numbers = new ArrayList<>(List.of(1, 2, 3, 4, 5, 6));
5
6// Remove even numbers backward
7for (int i = numbers.size() - 1; i >= 0; i--) {
8    if (numbers.get(i) % 2 == 0) {
9        numbers.remove(i);
10    }
11}
12System.out.println(numbers); // [1, 3, 5]

C / C++

c
1int arr[] = {10, 20, 30, 40, 50};
2int size = sizeof(arr) / sizeof(arr[0]);
3
4for (int i = size - 1; i >= 0; i--) {
5    printf("Index %d: %d\n", i, arr[i]);
6}
cpp
1#include <vector>
2#include <iostream>
3
4std::vector<int> vec = {10, 20, 30, 40, 50};
5
6// Using size_t (unsigned) — careful with underflow!
7for (size_t i = vec.size(); i-- > 0; ) {
8    std::cout << "Index " << i << ": " << vec[i] << "\n";
9}

C#

csharp
1int[] items = { 10, 20, 30, 40, 50 };
2
3for (int i = items.Length - 1; i >= 0; i--)
4{
5    Console.WriteLine($"Index {i}: {items[i]}");
6}
7
8// List backward removal
9var numbers = new List<int> { 1, 2, 3, 4, 5, 6 };
10for (int i = numbers.Count - 1; i >= 0; i--)
11{
12    if (numbers[i] % 2 == 0)
13        numbers.RemoveAt(i);
14}

Swift

swift
1let items = ["a", "b", "c", "d", "e"]
2
3for i in stride(from: items.count - 1, through: 0, by: -1) {
4    print("Index \(i): \(items[i])")
5}
6
7// Using reversed()
8for i in (0..<items.count).reversed() {
9    print("Index \(i): \(items[i])")
10}

Go

go
1items := []string{"a", "b", "c", "d", "e"}
2
3for i := len(items) - 1; i >= 0; i-- {
4    fmt.Printf("Index %d: %s\n", i, items[i])
5}

When to Use Backward Loops

Use CaseWhy Backward
Removing elements during iterationPrevents index shifting after removal
Reverse string/array processingNatural order for palindrome checks, reverse printing
Stack-like processing (LIFO)Process most recently added items first
Dependency resolutionProcess dependencies before dependents

Common Pitfalls

  • Off-by-one error on the start index: The last valid index is length - 1, not length. Starting at length causes an IndexOutOfBoundsException or buffer overflow.
  • Using unsigned integers for the loop counter: In C/C++, size_t is unsigned. The condition i >= 0 is always true for unsigned types, creating an infinite loop. Use for (size_t i = size; i-- > 0; ) or cast to a signed type.
  • Removing elements during a forward loop: Forward iteration skips elements after removal because indices shift down. Always iterate backward when removing elements by index.
  • Forgetting that range() stop is exclusive in Python: range(4, 0, -1) produces 4, 3, 2, 1 — it stops before 0. To include index 0, use range(4, -1, -1).
  • Modifying the loop variable inside the body: Changing i inside a backward loop can cause skipped elements or infinite loops. Let the loop control statement handle decrementing.

Summary

  • Loop backward with for (int i = length - 1; i >= 0; i--) in most languages
  • In Python, use range(len(items) - 1, -1, -1) or reversed(range(len(items)))
  • Backward loops are essential for safely removing elements during iteration
  • Watch for off-by-one errors and unsigned integer underflow in C/C++
  • Prefer language-specific utilities (reversed(), .reversed(), stride()) for readability

Course illustration
Course illustration

All Rights Reserved.