Indexing and Slicing Sequences
Strings are restricted to character elements only and are immutable; lists can hold any object type and are mutable; tuples can hold any object type but are immutable.
Try it: Indexing and Slicing
How Python indexes a sequence from 0 (or from the end with negative numbers) and how a slice start:stop:step picks positions — with the exact CPython rules for omitted and out-of-range bounds.
How it works
- Positions run 0 … len−1; negative positions count back from the end (−1 is the last).
- An index outside the string raises IndexError.
- A slice resolves start and stop (omitted → the ends; out of range → clamped), then walks by step, stopping before stop.
- A negative step walks backwards; a step of 0 is a ValueError.
Default run (7 steps): 'PYTHONIC'[1:6:2]: a slice copies characters from start up to (not including) stop, moving by step. … 'PYTHONIC'[1:6:2] → 'YHN' (positions 1, 3, 5).
Simplified: Works on a short string (up to 16 printable ASCII characters); lists slice by exactly the same rules.
Loading the simulation…
One Position, Three Behaviors
Strings, lists, and tuples are all ordered collections of elements. That shared structure gives them a common starting point: you can identify an element by its position. The important difference appears after you reach that position. A string contains characters only and cannot be changed in place. A list can contain any object type and can be modified. A tuple can contain any object type, but cannot be modified. Indexing therefore looks similar across the three types, while the operations allowed after access are different.
The same indexing mechanism does not mean the same mutability. Access is shared; modification rules are not.
Reading Ordered Positions
Indexing identifies an element by its position in an ordered sequence. The three sequence types use the same zero-based indexing mechanism, so the first position is represented by zero rather than one. This shared rule is one reason strings, lists, and tuples can often be handled in similar ways when a task only requires reading elements.
Finding an Element by Position
Consider an ordered sequence containing the elements A, B, and C. Which position identifies B?
Start counting at zero: The first element, A, has position 0.
Move to the next position: The second element, B, has position 1.
Apply the same structure: The third element, C, has position 2. This positional mechanism applies to strings, lists, and tuples.
B is identified by position 1 in this three-element sequence.
Slicing belongs to the same broader idea of working with ordered sequence positions: instead of focusing on one element, you work with a portion of a sequence. The supplied source establishes the shared indexing mechanism and the structural differences among strings, lists, and tuples, but it does not specify slice notation, endpoint rules, or negative-index behavior. Those details should not be inferred from the material covered here.
When an Update Is Allowed
Mutability describes whether the elements of a sequence can be changed after the sequence has been created. Lists are mutable, so modifying a list element succeeds. Strings and tuples are immutable, so modifying one of their elements is not permitted. An attempted string modification raises a TypeError. The same general constraint applies to tuples because they are also immutable.
Same Position, Different Result
Suppose a string, a list, and a tuple each contain two elements. Consider changing the element at position 0.
Read position 0: The position can be identified in all three sequence types because they share zero-based indexing.
Attempt the change in the list: The list is mutable, so its element at that position can be changed.
Attempt the change in the string: The string is immutable and restricted to character elements, so changing an individual character raises a TypeError.
Attempt the change in the tuple: The tuple is immutable, so changing an individual element is not permitted.
The position is accessed in the same way, but only the list accepts the element update.
Sequences Inside Sequences
A sequence can contain another sequence as one of its elements. This creates a sequence of sequences and allows structured data to be represented in layers. Lists and tuples can be nested in several combinations, including lists of tuples, lists of lists, tuples of tuples, and tuples of lists.
Following Two Levels of Structure
Consider a list whose element at one position is a tuple containing two values. How should you reason about the data?
Identify the outer sequence: The list is the first structural level. Its positions identify the elements stored by the list.
Find the inner sequence: One list element is a tuple rather than a single standalone value.
Work with the tuple: The tuple is itself an ordered sequence, so its own elements have positions.
Nested sequences let one indexed structure contain another indexed structure, which is useful for representing structured data.
Nesting does not erase the type of an inner sequence. A list inside a tuple remains a list, and a tuple inside a list remains a tuple, with its own mutability behavior.
Selecting the Sequence Type
| Sequence type | Allowed elements | Can elements be changed? | Good fit described by the source |
|---|---|---|---|
| String | Characters only | No | Text that does not need individual character updates |
| List | Any object type | Yes | Dynamic data whose elements may change, grow, or shrink |
| Tuple | Any object type | No | Fixed collections, including uses where immutability is desired |
Choose a string when the data is text and individual characters do not need to be modified. Choose a list when the sequence must be flexible: the source specifically identifies lists as suitable when elements may change or when the sequence may grow or shrink. Choose a tuple when the collection should remain immutable. The source also identifies tuples as useful when the sequence is intended to be used as a dictionary key or when accidental modification must be prevented.
A character-oriented text value belongs in a string when the characters do not need individual changes. A changing collection of mixed objects belongs in a list. A fixed collection of objects belongs in a tuple when preserving the collection against accidental modification is important.
Mistakes Beginners Make
Assuming that shared indexing means shared mutability.
Indexing describes how an element is accessed. It does not describe whether that element can be replaced.
Fix:
Check whether the sequence is mutable before planning an in-place change.Treating a string as a general-purpose collection of arbitrary objects.
Strings are restricted to character elements.
Fix:
Use a list or tuple when the sequence must contain arbitrary object types.Trying to modify a character directly inside a string.
Strings are immutable, and the attempted modification raises a TypeError.
Fix:
Convert the string to a list of characters, modify the list, and convert it back to a string if needed.Ignoring the mutability of an inner sequence.
The inner object keeps its own type. A tuple nested inside a list remains immutable.
Fix:
Evaluate the type of the specific inner sequence before attempting to modify it.
Practice the Choice
For each situation, choose string, list, or tuple and explain the deciding property: a text value whose individual characters will not change; a collection of mixed objects whose elements may change; a fixed collection that should not be accidentally modified; and a nested structure containing lists and tuples.
Hints
- Start by asking whether the data is character-only text.
- If the elements or the size may change, consider mutability.
- For nested data, identify the type of each outer and inner sequence separately.
What do you think happens?
A sequence uses zero-based indexing. If its elements are A, B, and C, which position identifies B, and which of the three sequence types can accept an element update?
Reveal answer
Answer: Position 1; only a list
The first position is 0, so B is at position 1. Lists are mutable, while strings and tuples are immutable.
Key Takeaways
- Strings, lists, and tuples are ordered sequence types that use the same zero-based indexing mechanism.
- Strings contain characters only and are immutable.
- Lists can contain any object type and are mutable, so their elements can be changed and the sequence can support dynamic data.
- Tuples can contain any object type but are immutable, making them suitable for fixed collections.
- Lists and tuples can be nested in combinations such as lists of tuples, lists of lists, tuples of tuples, and tuples of lists.
- Choose the sequence type based on the data it must contain and whether that data must remain fixed or be modified.
Key Takeaways
- All three sequence types support zero-based indexing, but their modification rules differ.
- Strings are character-only and immutable; lists accept any object type and are mutable; tuples accept any object type and are immutable.
- When text characters must change, convert the string to a list, modify it, and convert it back if needed.
- Nested lists and tuples represent sequences of sequences and can model structured data.
- Select a sequence type according to content, mutability, and whether the collection should remain fixed.