# Loops and Conditions in Python: for, while, range, enumerate, break, if/elif and match/case

URL: https://skillaria.top/en/guides/python/loops-and-conditions-python

Loops in Python repeat an action: for goes through the items of any collection or range(), while runs as long as its condition is true. You can stop a loop with break, skip an iteration with continue, and get the item number with enumerate(). Decisions are made with if/elif/else, and data can be sorted by shape with match/case (since Python 3.10).

Loops in Python let you repeat an action: go through a shopping list, process each line of a file, or keep asking the user until they enter a valid number. The language has two loops — `for` and `while` — and inside them the `if/elif/else` conditions and the `match/case` statement help you make decisions. Let us go through each tool with working examples.

## Conditions: if, elif, else

An `if` statement runs a block of code only when its expression is true. The block is marked by an indentation of 4 spaces — Python has no curly braces, and a wrong indentation immediately causes an `IndentationError`.

```
spent = 4200
limit = 5000

if spent > limit:
    print("Limit exceeded")
elif spent > limit * 0.8:
    print("Less than 20% of the budget left")
else:
    print("All good")
```

The `elif` branches are checked from top to bottom, and only the first matching one runs. That is why stricter conditions go higher up: if the check `spent > limit * 0.8` came first, the message about exceeding the limit would never appear.

### What counts as true

You do not always have to write a comparison in a condition. The values treated as false are `False`, `None`, zero (`0`, `0.0`) and empty collections: `""`, `[]`, `{}`. Everything else is true. That is why the check "the list is not empty" is written briefly:

```
expenses = []
if not expenses:
    print("No expenses yet")
```

Conditions can be combined with `and`, `or` and `not`, and a range is conveniently checked with a chained comparison: `if 0 < amount <= 100_000:`. For a short choice of value there is the ternary operator: `status = "high" if spent > limit else "normal"`.

## The for loop in Python: syntax and examples

The `for` loop in Python is not a counter, as in C, but an iteration over items. It takes each element of an iterable object in turn: a list, a string, a dictionary, a file or a range. This ordinary `for` is what other languages call foreach.

```
expenses = [350, 1200, 89, 4500]
total = 0
for amount in expenses:
    total += amount
print(total)  # 6139
```

The syntax of a for loop is `for variable in collection:`, followed by an indented block. After the loop the variable keeps its last value — sometimes that is useful, but relying on it in large programs is not a good idea.

### Looping over a string, a list and a dictionary

A string is iterated character by character, a list item by item. A loop over a dictionary goes over the keys by default; to get the key and the value together, use `.items()`:

```
by_category = {"food": 3200, "transport": 900, "cinema": 600}

for category, amount in by_category.items():
    print(f"{category}: {amount}")
```

To get only the values, use `.values()`. You cannot change the size of a dictionary during iteration — you will get `RuntimeError: dictionary changed size during iteration`. If you need to remove items, iterate over a copy: `for key in list(d):`.

## The range function: looping over numbers

When you need to iterate over numbers, `range()` comes to the rescue. It does not create a list in memory but yields the numbers one at a time, so `range(10**9)` works instantly.

| Call | Numbers |
| --- | --- |

| `range(5)` | 0, 1, 2, 3, 4 |

| `range(2, 6)` | 2, 3, 4, 5 |

| `range(0, 10, 3)` | 0, 3, 6, 9 |

| `range(5, 0, -1)` | 5, 4, 3, 2, 1 |

The main rule: the right boundary is not included. `range(1, 10)` ends at 9 — a frequent cause of "off-by-one" errors. The step can be negative, but not zero.

```
for i in range(1, 4):
    print(f"Day {i}")
# Day 1
# Day 2
# Day 3
```

## enumerate: a counter in a loop

Beginners often write `for i in range(len(items))` to know the item's number. It works, but it reads worse. The `enumerate()` function yields pairs "number, item", and the `start` parameter sets the number to count from:

```
items = ["coffee", "taxi", "lunch"]
for n, item in enumerate(items, start=1):
    print(n, item)
# 1 coffee
# 2 taxi
# 3 lunch
```

For iterating over two lists in parallel there is `zip()`: `for name, price in zip(names, prices):`. It stops at the shortest list; since Python 3.10 you can pass `strict=True`, and then lists of different lengths raise an error.

## The while loop in Python

A `while` loop repeats its block as long as the condition is true. It is chosen when the number of repetitions is not known in advance: waiting for correct input, reading data until the end, repeating a request until it succeeds.

```
balance = 10_000
month = 0
while balance > 0:
    balance -= 2_700
    month += 1
print(f"The money lasts for {month} months")  # 4
```

The main danger is forgetting to change the variable used in the condition. Then the loop never ends. If the program seems frozen, press Ctrl+C: Python will interrupt execution with a `KeyboardInterrupt`.

### Infinite loops and do while

Sometimes an infinite loop in Python is written on purpose: `while True:` with an exit through `break`. The same trick is used for a loop with the condition at the end — Python has no `do while` construct, and this pattern replaces it: the body runs at least once, and the check comes at the end.

```
while True:
    raw = input("Amount: ")
    if raw.isdigit():
        amount = int(raw)
        break
    print("Please enter a whole number")
```

A for loop is rarely infinite — only when it iterates over an endless iterator, for example `itertools.count()`.

## break and continue: leaving a loop and skipping an iteration

`break` stops the loop immediately, and execution continues with the code after it. `continue` skips the rest of the current iteration and moves on to the next one.

```
expenses = [350, -10, 1200, 0, 99_999, 89]

for amount in expenses:
    if amount  50_000:
        print("Suspicious amount, stopping")
        break             # leave the loop
    print(amount)
```

This prints 350 and 1200, then the message — the loop never reaches 89. Both statements act only on the nearest loop they are in.

### else on a loop

`for` and `while` have an unusual `else` branch: it runs if the loop finished on its own, without a `break`. This is handy for searching:

```
for amount in expenses:
    if amount > 50_000:
        print("Found a large expense")
        break
else:
    print("No large expenses")
```

## Nested loops

A loop inside a loop runs the inner one completely on every iteration of the outer one. This is how you walk through tables and matrices or iterate over pairs.

```
for row in range(1, 4):
    for col in range(1, 4):
        print(row * col, end="\t")
    print()
```

Keep two things in mind. First, the complexity grows quickly: two nested loops over 10,000 elements mean 100 million operations. Second, `break` leaves only the inner loop. To stop both, move the loops into a function and use `return` — that is cleaner than flags.

## The match/case statement

Since Python 3.10, a long chain of `if cmd == ... elif ...` can be replaced with the `match` statement (PEP 634). It is not just a switch: it matches a value against a pattern by the shape of the data and immediately unpacks the parts into variables.

```
def parse(text):
    match text.split():
        case ["add", item, amount]:
            return f"Add {item}: {amount}"
        case ["list"] | ["ls"]:
            return "Show expenses"
        case ["quit"]:
            return "Exit"
        case _:
            return "Unknown command"

print(parse("add Coffee 250"))  # Add Coffee: 250
print(parse("add Coffee"))      # Unknown command
```

The list pattern `["add", item, amount]` matches only a list of exactly three elements, the first of which is `"add"`. So a command without an amount goes to the `_` branch, which catches everything else. The `|` symbol combines alternatives.

### Dictionaries, types and guard conditions

A dictionary pattern checks only the keys listed; extra keys are ignored. The entry `int(a)` checks the type and captures the value, and an `if` after the pattern adds an extra condition (a guard):

```
match event:
    case {"type": "expense", "amount": int(a)} if a > 10_000:
        print("Large expense", a)
    case {"type": "expense", "amount": int(a)}:
        print("Expense", a)
```

### The main trap of match

A bare name in a `case` is a capture, not a comparison with a variable. `case limit:` matches any value and writes it into `limit`. To compare with constants, use a dotted name such as `case Color.RED:`, or literals.

The match syntax has barely changed since 3.10. Python 3.15 closed a small asymmetry: in literal patterns only a minus sign in front of a number used to be allowed, and now you can also write `case +1:`. On older versions such code will raise a syntax error.

## Common mistakes in loops

- **Changing a list during iteration.** Removing items inside a `for` skips the neighbouring ones. It is better to build a new list: `clean = [x for x in items if x > 0]`.
- **The range boundary.** `range(1, n)` does not include `n`.
- **Forgetting to change the condition in while** — an infinite loop.
- **Concatenating strings in a loop with +=** is slower on large volumes than `"".join(parts)`.
- **Assignment instead of comparison**: `if x = 5` is a syntax error; comparison is written with `==`.

## Loop exercises for practice

1. Calculate the sum and the average of a list of expenses, skipping negative values.
2. Print the multiplication table from 1 to 9 with nested loops.
3. Ask the user for numbers until they enter an empty line, then print the maximum.
4. Find the first number greater than 1000 in a list and report if there is none (use `for ... else`).
5. Parse the commands `add`, `del` and `list` with `match`.

## Summary

Python loops come down to two constructs: `for` iterates over the items of a collection or `range()`, and `while` keeps working while its condition holds. `break` and `continue` control the flow of a loop, `enumerate()` and `zip()` spare you manual counters, and `if/elif/else` with `match/case` handle decisions. All these tools are practised on an expense tracker example in a lecture of our Python course.

## FAQ

**How is for different from while in Python?**

for goes over a ready-made sequence and knows by itself when to stop, while repeats as long as the condition is true. If the number of repetitions is known or you have a collection, use for; if you are waiting for an event, use while.

**How do I loop in reverse order?**

Use reversed(items) for a collection or range(n - 1, -1, -1) for numbers. The reversed function does not copy the list; it iterates over it from the end.

**Does Python have a switch statement?**

There is no separate switch: its role is played by if/elif chains and the match/case statement introduced in Python 3.10. match can do more: it breaks lists and dictionaries down by shape and captures values.

**Which is faster — a loop or a list comprehension?**

A list comprehension such as [x * 2 for x in items] is usually a little faster than the equivalent loop with append, and shorter. For complex logic with several conditions, a regular loop is easier to read.

**How do I exit two nested loops at once?**

break only exits the inner loop. The simplest approach is to move the loops into a function and exit with return.


---
Source: Skillaria.Top (https://skillaria.top)
