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)\n# applied to [0..9]: [0,1,2,3,4]'

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

sliceA 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.