A Python list slice selects a half-open sequence range and creates a new outer list containing references to the selected objects.
Python list slicing: half-open ranges and shallow ownership
Operation contract
The dispatch fixture selects the middle two receipt identifiers, reverses their order and asks for a range beyond the available end. Slice bounds are clipped, so the oversized range returns an empty list. Direct indexing has a different contract: it must name an existing position. The final operation rejects a zero step instead of pretending it can make progress.
Failure and ownership boundary
A shallow slice does not recursively copy nested state. Reverse slicing materializes another list; reversed supplies an iterator instead. When a page reads a fixed window, distinguish clipped selection from a required count: a short slice does not prove enough records were loaded. Python lists: slicing copies the outer sequence, not nested objects and Python binary search: use a half-open interval and require sorted input depend on these ownership and endpoint rules.
Working program
receipts = [41, 42, 43, 44]
print(receipts[1:3])
print(receipts[::-1])
print(receipts[20:30])
try:
receipts[::0]
except ValueError:
print("zero step rejected")Output
[42, 43]
[44, 43, 42, 41]
[]
zero step rejectedCosts and limits
A slice with k selected entries takes O(k) time and O(k) outer-list storage. A full reverse slice therefore has O(n) retained references rather than bounded memory.
Common Mistakes
- A clipped slice is not the same as a validated pagination count.
- Nested objects remain shared after slicing.
Connected lessons
Python lists: slicing copies the outer sequence, not nested objects, Python generators: lazy iteration does not make retained output free, Python binary search: use a half-open interval and require sorted input.
