Loops (for) and Iterating Collections


1. Why do we need loops?

Loops let you repeat the same logic over many items without copy/paste.

You use loops when you need to:

Example: without a loop (bad)

numbers = [10, 20, 30, 40]

print(numbers[0] * 2)
print(numbers[1] * 2)
print(numbers[2] * 2)
print(numbers[3] * 2)

Example: with a loop (good)

numbers = [10, 20, 30, 40]

for n in numbers:
    print(n * 2)

2. What is a for loop?

In Python, for loops are mainly used to iterate over an iterable (something you can loop through), like:

Basic syntax

for item in iterable:
    # code that runs once per item
    print(item)

Important rules:


3. Iterating over collections

3.1 Loop over a list

Lists keep order and allow duplicates.

services = ["nginx", "redis", "postgres"]

for s in services:
    print("Starting", s)

When you need the index too: enumerate()

services = ["nginx", "redis", "postgres"]

for i, s in enumerate(services):
    print(i, s)

You can start counting from 1:

for i, s in enumerate(services, start=1):
    print(i, s)

3.2 Loop over a str

A string is a sequence of characters.

text = "DevSecOps"

for ch in text:
    print(ch)

Common use: count letters

text = "banana"
count_a = 0

for ch in text:
    if ch == "a":
        count_a += 1

print(count_a)

3.3 Loop over a tuple

Tuples are like lists but immutable (you can’t change them).

coordinates = (10, 20, 30)

for value in coordinates:
    print(value)

Tuples are often used to represent fixed structure data.


3.4 Loop over a set

Sets are unordered and contain unique values.

ports = {22, 80, 443, 80}

for p in ports:
    print("Checking port", p)

Notes:


4. Looping a specific number of times with range()

range(n) generates numbers from 0 up to n-1.

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

Output:

0
1
2
3
4

Start/stop/step

for i in range(2, 10, 2):
    print(i)

This prints:

2
4
6
8

5. Common patterns with for loops

5.1 Sum / accumulate

numbers = [3, 5, 10]
total = 0

for n in numbers:
    total += n

print(total)

5.2 Count items that match a condition

statuses = [200, 200, 404, 500, 200]
ok_count = 0

for code in statuses:
    if code == 200:
        ok_count += 1

print(ok_count)

5.3 Filter into a new list

numbers = [1, 2, 3, 4, 5, 6]
evens = []

for n in numbers:
    if n % 2 == 0:
        evens.append(n)

print(evens)

5.4 Build a string (careful)

words = ["dev", "sec", "ops"]
result = ""

for w in words:
    result += w + "-"

print(result)

6. break and continue

6.1 break (stop the loop)

numbers = [3, 7, 2, 9]

for n in numbers:
    if n == 2:
        print("Found 2")
        break
    print("Not 2:", n)

6.2 continue (skip to next iteration)

numbers = [1, 2, 3, 4, 5]

for n in numbers:
    if n % 2 == 1:
        continue
    print("Even:", n)

7. Nested loops (loop inside loop)

Useful for:

rows = [
    ["server1", "up"],
    ["server2", "down"],
]

for row in rows:
    for cell in row:
        print(cell)

8. Iteration summary (list vs str vs tuple vs set)

In all of them you can do:

for item in collection:
    print(item)

9. How a Python list is stored in RAM (and why it’s not like an array)

When people say “array”, they usually mean a low-level (C-style) array:

Python list is different.

9.1 A Python list is a dynamic array of references

In CPython (the normal Python you install), a list is implemented as:

So the list memory looks conceptually like this:

list:  [ ref -> obj,  ref -> obj,  ref -> obj,  ... ]

The objects those references point to are stored separately:

obj: int(10)     obj: str("hi")     obj: float(3.14)

That explains why a Python list can contain mixed types:

items = [10, "hi", 3.14]

9.2 “Next address” intuition

Inside the list itself, the references are contiguous (next to each other), so moving from index 0 to 1 is like moving to the “next slot”.

But the actual objects (like the int or str) are not guaranteed to be stored next to each other.

You can see that each element is a separate object by looking at its identity:

items = [10, 11, 12]

for x in items:
    print(x, id(x))

id(x) is the identity/address-like value of that object (implementation detail, but useful for intuition).

9.3 Why it’s not the same as a low-level array

Key differences:

9.4 What this means in practice