Understanding Python’s range(): Why Stop Feels Like n+1

Understanding Python’s range(): Why Stop Feels Like n+1
Photo by Sergio Mena Ferreira / Unsplash

When learning Python loops, one of the most common questions beginners ask is:
Why do I need to put 7 in range(1, 7) just to print numbers from 1 to 6?

The answer lies in how Python’s range() function is designed. Let’s break it down thoroughly, so you can not only use it but also remember the reasoning behind it.


The Basics of range()

The range() function generates a sequence of numbers. Its full signature is:

range(start, stop, step)
  • start → the first number in the sequence (default is 0).
  • stop → the number where the sequence ends, but not included.
  • step → the difference between each number (default is 1).

So:

for i in range(1, 7):
    print(i)

produces:

1
2
3
4
5
6

Notice that 7 is excluded. That’s why it feels like you’re writing n+1.


Why Does Python Exclude the Stop Value?

This design is not an accident. Python (like many other programming languages) uses half-open intervals [start, stop). That means:

  • The sequence includes the start.
  • The sequence excludes the stop.

This has several practical benefits:

  1. Length is easy to compute
    The number of items in range(start, stop) is simply stop - start.
    Example: range(1, 7) → length = 7 - 1 = 6.

Simplicity in loops
If you want to loop through all items in a list:

for i in range(len(nums)):
    print(nums[i])

You don’t need to write len(nums) - 1. The exclusion of stop makes the loop clean.

Consistency with indexing
Lists, strings, and other sequences in Python use the same half-open style.
For example:

nums = [10, 20, 30, 40, 50]
print(nums[1:3])  # [20, 30]

Index 1 is included, but index 3 is excluded.


Common Pitfall: Thinking of Stop as “the Last Number”

A lot of confusion happens when people assume stop means “the last number I want.”
Instead, it’s better to think of stop as “where you stop counting.”

So if you want numbers from 1 to n, you must write:

for i in range(1, n + 1):
    print(i)

That extra +1 is natural once you remember that stop is excluded.


Using step for More Control

Don’t forget the third parameter: step.

Examples:

# Count by 2
for i in range(1, 10, 2):
    print(i)
# 1, 3, 5, 7, 9

# Count backwards
for i in range(5, 0, -1):
    print(i)
# 5, 4, 3, 2, 1

The step value gives you flexibility beyond just sequential counting.


Other Considerations

Negative ranges
You can use negative numbers too:

for i in range(-3, 2):
    print(i)
# -3, -2, -1, 0, 1

Convert to list if needed
If you want to see the actual sequence:

print(list(range(1, 7)))
# [1, 2, 3, 4, 5, 6]

Large ranges are lazy
range() doesn’t create a full list in memory. Instead, it generates numbers on the fly, making it memory-efficient even for huge ranges:

big_range = range(1, 10_000_000)
print(len(big_range))  # 9999999

Finally

The rule to remember is simple:

  • Start is included.
  • Stop is excluded.
  • Step controls the jump.

So when you write:

for i in range(1, 7):
    print("Number:", i)

you’re really saying:
“Start at 1, keep going up by 1, but stop before you reach 7.”

That’s why programmers often think of the stop value as n+1 when they want to include n in the loop.


Key takeaway: Always treat stop as the boundary rather than the last number. This mindset will make Python loops and slicing much easier to understand and use.

Support Us

Share to Friends