slice()

The thing that `x[i:j:k]` builds. Rarely constructed directly, but essential when writing __getitem__ or extended indexing.

Built-in function / typePython 1.0+Live demo
Common call
s = slice(2, 10, 2)
Returns
a slice object — usable via x[s]
Replaces
passing three variables to describe an index range
Watch out
like range, stop is EXCLUSIVE; unlike range, negative step counts down
slice(stop) / slice(start, stop[, step])
→ slice

Demo

Live evaluation
Try:
Inputs
startintstart index (empty = None)
stopintstop index (exclusive)
stepintstep (empty = 1)
Output
slice(None, 5)
slice(None, 5, None)

slice() builds a slice object — the same thing that `x[i:j:k]` syntax creates. The demo shows the slice object AND how it would apply to a demo list. Any argument can be omitted (None) — for "from the start" use start=None; for "to the end" use stop=None. Negative indices count from the end of the sequence. Negative step counts down.

Parameters

NameTypeRequiredDescription
startint | Noneno (None)The first index (inclusive). None means "from the beginning". In the one-arg form (`slice(stop)`), start defaults to None.
stopint | NoneyesThe upper bound (exclusive). None means "to the end". The only argument in the one-arg form.
stepint | Noneno (None)The stride. None means 1. Negative values step backward.

Return value

slice — A slice object with .start, .stop, .step attributes. Any of the three can be None. Slice objects are what `x[i:j:k]` syntax creates behind the scenes and passes to __getitem__.

Common patterns

When would you construct one explicitly?
Usually you just write `x[i:j:k]`. slice() is useful when the arguments are variables you compute.
s = slice(start, stop, step)
result = data[s]
Custom __getitem__ handling
When implementing a container, __getitem__ receives a slice object for extended indexing.
class Vec:
    def __getitem__(self, key):
        if isinstance(key, slice):
            return self._range(key.start, key.stop, key.step)
Slice indices helper
slice.indices(length) clips a slice to a sequence length and returns concrete (start, stop, step).
s = slice(-3, None)
s.indices(10)   # (7, 10, 1)
Reusable named slices
When the same slice pattern is used in many places.
HEADER = slice(0, 8)
BODY   = slice(8, None)
header, body = data[HEADER], data[BODY]

Examples

1. One-arg (stop only)
slice(5)
Returns
slice(None, 5, None)
2. Two-arg
slice(2, 8)
Returns
slice(2, 8, None)
3. Three-arg
slice(0, 20, 2)
Returns
slice(0, 20, 2)
4. Applied to a list
[1,2,3,4,5][slice(1, 4)]
Returns
[2, 3, 4]
5. Reverse
[1,2,3,4,5][slice(None, None, -1)]
Returns
[5, 4, 3, 2, 1]
6. slice.indices
slice(-3, None).indices(10)
Returns
(7, 10, 1)

Pitfalls

1. The one-arg form takes STOP, not start
A common typo. `slice(5)` is equivalent to `slice(None, 5, None)` — start defaults to None, stop is the given value. Mirrors the range constructor.
Assumed start
slice(5)
slice(None, 5, None) # NOT slice(5, None)
Two-arg for start
slice(5, None)
slice(5, None, None)
2. None is the default — do NOT confuse with 0
`slice(None, 5)` is not the same as `slice(0, 5)` — they behave the same for positive stops but differ subtly in some __getitem__ implementations. Use None to signal "default".
Zero as default
slice(0, 5, 1)
explicit start
None as default
slice(None, 5, None)
canonical "default" form
3. slice is a TYPE — its constructor returns a slice object
Like list or dict, slice is both the type name and its constructor. Calling `slice(...)` returns an instance; you would rarely subclass it.
Assumed function
type(slice(5))
<class 'slice'>
It is a type
isinstance(slice(5), slice)
True
4. slice is not iterable
You cannot iterate a slice directly — it is only meaningful when applied to a sequence via __getitem__. To get the actual indices, use slice.indices(length) then range().
Direct iter fails
for i in slice(5): ...
TypeError: 'slice' object is not iterable
Use indices + range
for i in range(*slice(0, 5).indices(len(x))): ...
concrete indices

When to use

Use it
  • Custom __getitem__ that supports extended indexing
  • Reusable named slices for readable code
  • Slicing when the endpoints are computed at runtime
  • Interfacing with numpy / pandas / other libraries that consume slice objects
Reach for something else
  • Literal slice → just write x[i:j:k]
  • Iteration → use range() instead
  • Storage of index ranges as a tuple — a slice object is dedicated for the job

Notes

Complexity
O(1) construction
Return
A slice object with .start, .stop, .step attributes
CPython impl
Objects/sliceobject.c :: PySlice_New
Memory
Small fixed-size allocation
Thread-safe
Yes — slice objects are immutable

FAQ

When the start/stop/step values are variables you compute at runtime, or when you want to store a slice as a named constant. In everyday code you just write x[i:j:k] — Python calls slice() for you.

History

1.0
slice() has been a builtin since Python 1.0.
2.3
slice.indices() method added for clipping to sequence length.