Python range() Inclusive Stop: Positive and Negative Steps

Quick answer: Python range() excludes its stop value. To include an endpoint, use range(start, stop + 1) for a positive step or range(start, stop – 1, -1) for a negative step, while checking empty and stepped ranges explicitly.

Python inclusive range infographic showing exclusive stop, positive and negative endpoint adjustments, zero step, direction, and lazy values
Inclusive ranges are a boundary policy: direction, step, and endpoint alignment all matter.

Python’s range() is not fully inclusive. It includes the start value, but it excludes the stop value. That means range(1, 5) gives 1, 2, 3, 4, not 1, 2, 3, 4, 5.

If you want an inclusive range, adjust the stop value in the direction you are counting. For a normal positive step, add 1 to the stop value. For a negative step, subtract 1 from the stop value.

Python range() syntax

range(stop)
range(start, stop)
range(start, stop, step)

The official Python range documentation describes range as an immutable sequence type. It stores the start, stop, and step values instead of building a list of every number. The built-in function is also listed in the official range() documentation.

  • start: the first value. If omitted, Python starts at 0.
  • stop: the boundary where the sequence stops. This value is excluded.
  • step: the difference between values. If omitted, Python uses 1.

Is Python range inclusive or exclusive?

range() is start-inclusive and stop-exclusive.

print(list(range(1, 5)))

Output:

[1, 2, 3, 4]

The 1 is included because it is the start value. The 5 is excluded because it is the stop value.

Python Pool infographic showing range start, stop, step, and exclusive endpoint
range stops before the endpoint, so an inclusive sequence needs a deliberate adjustment.

Make range inclusive for positive steps

For a positive step, pass stop + 1 to range().

for number in range(1, 5 + 1):
    print(number)

Output:

1
2
3
4
5

The same pattern works when the step is larger than 1, as long as the stop value is actually reachable by that step.

print(list(range(2, 10 + 1, 2)))

Output:

[2, 4, 6, 8, 10]

This is one of the most common off-by-one fixes in Python loops. If your loop index is used to access a list, be careful not to go past the final valid index. Our Python list index out of range guide explains that error in more detail.

Make range inclusive for negative steps

When counting down, the step is negative. In that case, subtract 1 from the stop value.

print(list(range(5, 1 - 1, -1)))

Output:

[5, 4, 3, 2, 1]

If you wrote range(5, 1, -1), Python would stop before 1:

print(list(range(5, 1, -1)))

Output:

[5, 4, 3, 2]

Reusable inclusive_range() helper

If you need inclusive ranges in several places, use a small helper that adjusts the boundary based on the sign of step.

def inclusive_range(start, stop, step=1):
    if step == 0:
        raise ValueError("step cannot be zero")

    if step > 0:
        return range(start, stop + 1, step)

    return range(start, stop - 1, step)

print(list(inclusive_range(1, 5)))
print(list(inclusive_range(5, 1, -1)))

Output:

[1, 2, 3, 4, 5]
[5, 4, 3, 2, 1]

This helper does not force impossible values into the sequence. For example, inclusive_range(1, 8, 3) returns 1, 4, 7 because 8 is not reachable by repeatedly adding 3.

Python Pool infographic mapping an inclusive end through stop plus step to range values
For integral steps, adjust the stop so the intended endpoint is included.

Using range with for loops

range() is usually used with a for loop:

for index in range(0, 3):
    print(index)

Output:

0
1
2

If you need to stop a loop early, use break inside the loop body. See our fixed guide to SyntaxError: ‘break’ outside loop if your loop control statement is in the wrong place.

Python range vs xrange

In Python 3, use range(). The old xrange() function exists only in Python 2. Python 3’s range() already behaves like a compact sequence object, so you do not need xrange() for memory reasons in modern Python.

If you are maintaining Python 2 code, our xrange in Python article covers that older function. For new code, avoid xrange().

Python Pool infographic comparing descending start, stop, negative step, and inclusive end
Descending ranges need a stop adjustment in the same direction as the negative step.

Common mistakes

  • Calling range(1, 5) inclusive: it stops before 5.
  • Adding 1 while counting down: use stop - 1 when step is negative.
  • Using step=0: Python raises ValueError because the sequence cannot move.
  • Converting every range to a list: do this for display or testing, but loop over the range object directly in normal code.
  • Mixing integer boundaries with float logic: range() works with integers. If you are handling numeric conversions, review int to float in Python and integer division in Python.

FAQ

Does range include the start value?

Yes. range(start, stop) includes start.

Does range include the stop value?

No. range() excludes stop. Use stop + 1 for a positive inclusive integer range, or stop - 1 for a negative inclusive integer range.

Can range count backward?

Yes. Use a negative step such as range(5, 0, -1).

Conclusion

Python range() is inclusive at the start and exclusive at the stop. To include the stop value, adjust the stop boundary by one step in the direction you are counting. Use range(start, stop + 1) for upward integer loops and range(start, stop - 1, -1) for downward integer loops.

Make The Stop Policy Explicit

range(start, stop, step) produces values from start toward stop but never includes stop. This half-open convention makes adjacent ranges compose without repeating a boundary. When a problem statement says the endpoint is inclusive, adjust the stop based on direction and step instead of adding one blindly.

def inclusive_range(start, stop, step=1):
    if step == 0:
        raise ValueError("step must not be zero")
    adjusted_stop = stop + 1 if step > 0 else stop - 1
    return range(start, adjusted_stop, step)

print(list(inclusive_range(2, 5)))
print(list(inclusive_range(5, 2, -1)))
Python Pool infographic testing zero steps, empty ranges, floats, bounds, and validation
Check zero-step errors, empty ranges, integer requirements, bounds, and off-by-one behavior.

Check Direction, Step, And Empty Results

A positive step cannot move from a larger start toward a smaller stop, and a negative step cannot move upward. In those cases the range is empty. For a step of 2, the requested endpoint may not land on the sequence at all.

Keep range Lazy And Predictable

range stores its arithmetic description rather than a full list of values. Use it directly in loops, convert to a list only when materialization is needed, and test the first, last, and length behavior for boundary-sensitive code. For a floating increment, use a numeric loop or a library designed for floating-point sequences.

Frequently Asked Questions

Does Python range() include the stop value?

No. range() includes start when the sequence is non-empty but excludes stop.

How do I make a positive range inclusive?

Use range(start, stop + 1) when a positive step of one and an integer endpoint are intended.

How do I make a negative range inclusive?

Use range(start, stop – 1, -1) for a descending sequence with a negative step of one.

What happens when range() gets step zero?

A zero step raises ValueError because the sequence cannot make progress toward its stop value.

Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted