In Python, the expression for i in range(4): iterates four times, with i taking the values 0, 1, 2, and 3. This sequence starts at 0 by default and stops before the stop value, producing a predictable, zero-based index that is ideal for controlled repetition. You can use this pattern to index lists, build new collections, accumulate results, or drive nested logic with stable, readable code.
How range Works in Python
The built-in range function generates an arithmetic progression of integers without creating a list in memory. It accepts one to three integer arguments: range(stop), range(start, stop[, step]). When called with a single argument as in range(4), the start defaults to 0 and the step defaults to 1. The resulting sequence advances by step until it reaches or exceeds stop, always staying exclusive of the stop value. This design supports constant memory use and reliable integer progression.
Signature and parameters
| Parameter | Description | Default |
|---|---|---|
| start | First value of the sequence | 0 |
| stop | Exclusive boundary; iteration ends before this value | required |
| step | Increment between consecutive values | 1 |
Execution of for i in range(4)
When Python evaluates for i in range(4):, it produces the sequence 0, 1, 2, 3. On each iteration, the loop variable i is assigned the next integer, and the indented block executes. After the last value (3), the loop exits without reaching 4. You can observe this explicitly by collecting values into a list, such as list(range(4)), which yields [0, 1, 2, 3]. The behavior is deterministic and independent of platform or runtime version.
Common Use Cases and Patterns
Using for i in range(4) is effective when you need an exact number of iterations and either require an index or want to repeat an action. Common patterns include:
- Processing elements by index when you also need the position.
- Building lists or accumulating results with controlled counts.
- Driving counters, timeouts, or fixed-step simulations.
- Running setup or teardown logic a known number of times.
Index-based element access
When paired with a sequence such as a list, for i in range(4) provides an index to access elements by position. This is useful when you must modify items in place or work with multiple sequences aligned by index. Ensure the index stays within the target sequence bounds to avoid runtime errors.
Accumulating results
Inside the loop, you can append to a list, sum values, or update a dictionary. Because the number of iterations is predetermined, you can preallocate lists or initialize accumulators before the loop, which can improve clarity and performance.
Pitfalls and Edge Cases
Several subtle issues can arise when using for i in range(4). Relying on i outside the loop can lead to bugs, since i retains its last value in some Python implementations. Modifying the underlying sequence while iterating by index may cause skipped elements or exceptions. Iterating over a range of length zero (e.g., range(0) or range(2, 2)) produces zero iterations, which is valid and often used in conditional guards.
Common mistakes to avoid
- Assuming
ialways starts at 1; it actually starts at 0. - Using
range(len(sequence))when a direct iteration over items would be safer and more idiomatic. - Mutating the list you are indexing in ways that shift element positions.
- Confusing
range(4)with values 1–4; it represents 0–3.
Advanced Patterns and Alternatives
Python offers additional tools that can replace or complement for i in range(4). enumerate(sequence) supplies both index and value, improving readability. zip pairs multiple iterables, and list comprehensions allow concise construction of new collections. For numeric work, libraries such as NumPy provide vectorized operations that can outperform explicit Python loops.
Readable alternatives
| Pattern | Use when you need | Notes |
|---|---|---|
for i in range(4) |
Exact number of iterations with an index | Simple, explicit, zero-based |
for item in sequence |
Direct element access without index | |
for i, item in enumerate(sequence) |
Both index and element with clarity | Preferred over range(len(sequence)) |
Performance Considerations
range is implemented as a lightweight, lazy sequence in both Python 3 and modern Python 2 codebases, so memory overhead is minimal. The for-loop itself adds negligible cost per iteration. If performance is critical and the loop body is small, examining interpreter warmup, algorithmic complexity, or moving computation to optimized libraries may help. For most scripts, clarity and correctness outweigh micro-optimizations.
Best Practices and Recommendations
Write predictable loops by keeping the range explicit, avoiding side effects on loop variables, and using descriptive variable names when the index carries meaning. Validate bounds before indexing, and prefer idiomatic constructs like enumerate when both position and value are needed. Document why a fixed count such as range(4) is necessary, especially when the magic number 4 represents a domain rule or configuration.
Summary and Key Takeaways
The pattern for i in range(4): yields the values 0, 1, 2, 3 and is a reliable way to execute code exactly four times with an index. It is memory-efficient, deterministic, and widely supported across Python versions. Use it when you need an explicit count or index, but prefer more expressive constructs like enumerate when readability allows. Understanding edge cases and common mistakes helps you write robust, maintainable Python code.