This rule raises an issue when a nested loop uses the same variable name as an outer loop, causing the inner loop to shadow the outer loop variable.

Why is this an issue?

In Python, loop variables persist after the loop completes and can be reassigned by inner loops without any warning. Unlike languages with block-scoped variables, Python allows inner loops to silently overwrite outer loop variables, making the outer variable inaccessible within the inner loop scope.

This happens because Python’s for loop assigns the loop variable in the current scope, regardless of whether a variable with that name already exists. When you write:

for i in range(10):
    for i in range(5):
        pass

The inner loop reassigns i on each iteration, completely replacing the value from the outer loop. After the inner loop completes, i contains the last value from the inner loop (4), not the current value from the outer loop.

This pattern almost always indicates a programmer error rather than intentional behavior. Common scenarios include:

The shadowing happens silently without any compiler or runtime warning, making these bugs difficult to spot during code review and testing.

What is the potential impact?

Using the same variable in nested loops leads to logic errors that can be difficult to debug:

How to fix it

Use different variable names for each loop. Choose descriptive names that reflect what each variable represents.

Code examples

Noncompliant code example

for i in range(10):
    print(f"Outer: {i}")
    for i in range(5):  # Noncompliant
        print(f"Inner: {i}")
    # i now contains 4, not the outer loop value

Compliant solution

for i in range(10):
    print(f"Outer: {i}")
    for j in range(5):
        print(f"Inner: {j}")
    # i still contains the outer loop value

Resources

Documentation

Related rules