1.1Readable slicing in production code
A slice with half-open bounds is the difference between `a[:n]` + `a[n:]` composing perfectly and staring at off-by-one errors at 2 AM.
WHAT IT IS
Think of slices like train cars: each car has a number, but you board at the front edge of car N and get off at the front edge of car M. The car at the stop edge stays outside the ride. That is half-open: start included, stop excluded.
The beauty is composition. If you split a list at index n, `a[:n]` and `a[n:]` cover every element exactly once. No overlap, no gap. That is the point of half-open ranges.
HOW IT WORKS
- 1Python normalizes omitted bounds and negative indices against the sequence length before performing the slice.
- 2For built-in sequences, slicing creates a new container and copies references (or values for flat types) for the selected range. List slicing allocates proportional to the slice length.
- 3Stride values change traversal order. `[::-1]` reverses. `[::2]` skips every other. Stride still allocates a copy, even if you are skipping elements.
WHEN TO USE IT
- Use slicing when position ranges are the natural model and the caller already thinks in offsets.
- Name common slices with `slice(0, 8)` instead of bare `[:8]`, so the name carries domain meaning.
- Avoid large slices in hot paths when an iterator or view approach is enough.
KEY TAKEAWAYS
- Half-open ranges eliminate off-by-one drift when composing adjacent slices.
- List slicing allocates every time. The copy is the hidden cost.
- Negative strides are expressive but still pay full allocation cost.
TRY IT OUT!
items = [10, 20, 30, 40, 50, 60] middle = items[2:5] reverse_every_other = items[::-2] print(middle, reverse_every_other)