Loops: repeat things
Repeating an action many times is how one attacker tries 10,000 passwords in a minute, or how one defender checks 1,000 log lines for a pattern. Loops turn "one" into "many."
for — do X for each item
The for loop walks through each item of something and runs a block of code for each one.
ports = [22, 80, 443, 3306]
for port in ports:
print(f"Checking port {port}...")
Read it in English: "for each port in the list ports, print a message." Same shape works on:
# Each character of a string:
for char in "kashsec":
print(char)
# Each line of a file:
with open("hosts.txt") as f:
for line in f:
print(line.strip())
# Each key/value in a dict:
user = {"name": "admin", "id": 1}
for key, value in user.items():
print(f"{key} = {value}")
range — counting loops
range(n) gives you the numbers 0, 1, 2, ..., n-1. Perfect for "do this N times."
for i in range(5):
print(i) # 0 1 2 3 4
for i in range(1, 11): # start, stop
print(i) # 1..10
for i in range(0, 100, 10): # start, stop, step
print(i) # 0 10 20 ... 90
Handy pattern for retries:
for attempt in range(1, 4): # attempts 1, 2, 3
print(f"Attempt {attempt}")
# try something...
while — keep going until a condition changes
while runs as long as its condition is True.
count = 5
while count > 0:
print(count)
count -= 1
print("Boom!")
# Common shape — read input until user says stop:
answer = ""
while answer.lower() != "quit":
answer = input("> ")
print(f"You said: {answer}")
When to use which?
for— you already know what you're iterating over (a list, a range, a file).while— you don't know how many times you'll loop; you'll stop when a condition changes.
break and continue
Two escape hatches inside loops:
break— leave the loop entirely.continue— skip the rest of this iteration and go to the next one.
for line in open("emails.txt"):
line = line.strip()
if not line:
continue # skip empty lines
if line == "STOP":
break # end the loop
print(f"Processing: {line}")
Avoiding accidental infinite loops
A while loop only stops when its condition becomes false — if you forget to actually update the variable the condition depends on, the loop runs forever, freezing your script (and sometimes your terminal):
# BUG: count never changes, this loop never ends
count = 0
while count < 5:
print("stuck")
# forgot: count += 1
# FIXED:
count = 0
while count < 5:
print(count)
count += 1 # this line is what actually lets the loop finish
If a script you run seems to hang forever with no output, an infinite loop is one of the first things worth suspecting — Ctrl+C in the terminal force-stops it, and re-reading your loop's condition (and whether anything inside the loop actually changes it) is the fix.
Nested loops
You can put a loop inside another loop. Useful for combinations like "every user × every password":
users = ["admin", "root", "user"]
passwords = ["password", "123456", "letmein"]
for user in users:
for password in passwords:
print(f"Trying {user}:{password}")
That's genuinely the shape of a login brute-force script. In Path 11 you'll build a responsible, in-lab-only version of this against a deliberately-vulnerable target.
The security learner's most-used loop pattern
Reading a wordlist, doing something with each entry:
with open("subdomains.txt") as f:
for name in f:
name = name.strip()
full = f"{name}.example.com"
# try to resolve it, HTTP-probe it, etc.
print(full)
If you find yourself doing something 5+ times manually, that's a signal to write a loop.
List comprehensions — a Pythonic shortcut
For simple "make a new list from another list" work, Python has a beautiful one-line syntax:
# Regular way:
squared = []
for n in [1, 2, 3, 4, 5]:
squared.append(n * n)
# Comprehension:
squared = [n * n for n in [1, 2, 3, 4, 5]]
# With a filter:
even_ports = [p for p in ports if p % 2 == 0]
# String cleanup pattern you'll use constantly:
lines = [line.strip() for line in open("hosts.txt") if line.strip()]
Comprehensions are idiomatic Python. Learn to recognise them; use them when they don't hurt readability.
enumerate — index and value together
When you need both position and value:
for index, port in enumerate(ports, start=1):
print(f"{index}. Port {port}")
zip — walk two lists in parallel
users = ["alice", "bob", "carol"]
scores = [92, 87, 78]
for user, score in zip(users, scores):
print(f"{user}: {score}")
🧪 Lab — Port sweeper (safe local version)
Save as sweep.py and run only against 127.0.0.1 (your own machine — always in scope!).
# sweep.py — a beginner port sweeper against your own machine
import socket
TARGET = "127.0.0.1"
PORTS_TO_CHECK = [22, 80, 139, 443, 445, 3306, 3389, 5432, 8080]
print(f"Sweeping {TARGET}...")
open_ports = []
for port in PORTS_TO_CHECK:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(0.5)
try:
s.connect((TARGET, port))
print(f"[+] {port} OPEN")
open_ports.append(port)
except (socket.timeout, ConnectionRefusedError):
print(f"[-] {port} closed")
finally:
s.close()
print(f"\nSummary: {len(open_ports)} open ports: {open_ports}")
Notice you already have the shape of a real security tool — a loop, a network operation, exception handling, and a summary. You'll add features throughout Path 04.
127.0.0.1 is your own machine, so this is fine. Scanning any other IP, even briefly, without permission is illegal — see Path 01 lesson 4. Use scanme.nmap.org if you want to try against something not yours.
You want to print the numbers 1 to 100 inclusive. Which is the correct range()?
- A.
range(100) - B.
range(1, 100) - C.
range(1, 101)
Show answer
C —range(1, 101). range is exclusive at the end, so range(1, 100) stops at 99.Key terms
forloop — repeat for each item.whileloop — repeat while a condition is true.range()— generate a sequence of numbers.break/continue— leave / skip an iteration.- List comprehension — one-line list construction.
enumerate/zip— index+value / parallel iteration.
Recap
forwalks over items;whileruns while a condition holds.range(a, b, step)is your counting loop.breakexits,continueskips.- List comprehensions turn small loops into one readable line.
- Loops turn "one attempt" into "one thousand attempts" — the heart of a lot of tooling.
References
Next up → Error handling & exceptions