CS1010E Chap.6 Objects and Mutable Sequences
Objects and Mutable Sequences
Names refer to objects
This chapter changes how you read an assignment statement. In Python every value, from the integer 1 to a long list, is an object created in memory, and a variable is only a name that refers to such an object. Two names can refer to one object, and the is operator tells you when they do.
The == operator answers a different question: whether two objects hold equal content. id(x) exposes the address of the object behind a name, which is handy when you want to confirm what a diagram claims.
Objects come in two families. Immutable objects, which include int, float, bool, str and tuple, cannot have their contents changed after creation.
A name bound to one of them can only appear to change by being rebound to a different object. Mutable objects can be edited where they sit, and the list is the first mutable sequence the course introduces.
Like a tuple it stores an ordered sequence, but you may assign to an index, assign to a slice, or call methods that alter it.
Why mutability causes surprises
When two names share a mutable list, an edit made through one name is visible through the other. The edit you intended is the primary effect; the change seen through the second name is a side effect.
Function calls make this common, because passing an argument is an implicit assignment to the parameter. The parameter and the caller’s variable therefore share the same list, and an indexed write inside the function reaches back into the caller’s data.
The memory model explains why: local names live in activation records on the stack, while the objects they refer to are created on the heap and outlive any single call.
The standard protection is a copy. Slicing the whole list with lst[:] or calling lst.copy() creates a new list object whose elements are the same objects as before.
Rebinding a parameter to such a copy at the start of a function stops later writes from leaking out, and assignment rules in this course explicitly require that a function leave its original input unmodified.
Building lists declaratively
The chapter closes with list comprehension, a compact expression such as [i**2 for i in range(11)] that produces a new list, optionally filtered by an if clause.
Because the result is always a fresh mutable list, a comprehension is also a natural way to compute a transformed version of your input without touching the original.
Objects also carry methods, applied with the dot operator. lst.copy() is one; append, sort and count are others worth exploring in the shell.
Notice which of them edit the list itself and which only read it, because that distinction decides whether an alias will see a change.
What this chapter covers
- 01
Every value in Python is an object
- 02
Identity with is versus equality with ==
- 03
Immutable types: int, float, bool, str, tuple
- 04
Lists as mutable sequences: index and slice assignment
- 05
Aliasing and side effects between shared names
- 06
Pass by object reference into functions
- 07
Stack frames and heap objects in the memory model
- 08
Copying with slices, lst.copy() and list comprehension
Worked example · free
Tracing an alias, a copy and a slice assignment
grid = [5, 1, 4], alias = grid, snap = grid.copy(), alias[1:2] = [2, 3] and grid[0] = 0. State the final contents of grid, alias and snap, the values of grid is alias and grid is snap, and the result of [v for v in grid if v % 2 == 0]. The step weighting shown here is an AskSia study allocation and is not a University marking scheme.other also reads [4, 60, 8]. Plain assignment points nums at a fresh object and leaves other untouched.- 2Identify that
alias = gridshares one list whilegrid.copy()creates a second list object. - 2Apply the slice assignment and the indexed write to the shared list only, leaving the copy unchanged.
- 2Answer the identity tests and evaluate the filtered comprehension on the final list.
grid and alias, holding [5, 1, 4], and a separate copy named snap with the same contents. The slice assignment alias[1:2] = [2, 3] replaces the element at index 1 with two elements, so the shared list becomes [5, 2, 3, 4]. Then grid[0] = 0 edits the same list, giving [0, 2, 3, 4]. Both grid and alias print [0, 2, 3, 4], while snap still prints [5, 1, 4] because neither edit touched it. grid is alias is True and grid is snap is False. The comprehension keeps the even values of the final list and returns a new list, [0, 2, 4].name = ... assignment.Key terms
- Object
- Holds a value in memory together with its type; every Python value, including a plain integer, is one.
- Identity Operator
- Tests with
iswhether two names refer to the very same object, rather than to objects with equal content. - Immutable Object
- Keeps its contents fixed after creation, as int, float, bool, str and tuple objects do; a name bound to one changes only by rebinding.
- Mutable Sequence
- Stores an ordered collection whose elements can be reassigned in place; the list is the main example in this course.
- Side Effect
- Produces an observable change beyond an operation's primary effect, such as a second name seeing a list edited through the first.
- Pass by Reference
- Describes how a call assigns each argument to its parameter, so both names refer to the same object during the call.
- Heap Memory
- Stores objects when they are created, separately from the stack, which holds activation records and their local names.
- List Comprehension
- Builds a new list from an expression over an iterable, with an optional if clause to filter elements.
Objects and Mutable Sequences FAQ
Why does changing one list change another list in Python?
Both variables almost certainly refer to the same list object, usually because of an assignment like b = a or because the list was passed into a function. An indexed or slice assignment edits that single object, so every name pointing at it shows the change. Check with the is operator.
What is the difference between is and == in Python?
The double equals sign compares content, so two separate lists holding [1, 2] are equal. The is operator compares identity and is True only when both names refer to one object. Use == for values; reserve is for questions about sharing.
Does Python pass arguments by value or by reference?
Arguments are passed by object reference: the parameter becomes another name for the caller's object. Reassigning the parameter inside the function only moves the local name, but writing to an index or slice of a list parameter changes the caller's list.
How do I copy a list so that edits do not affect the original?
Use a full slice such as nums[:], call nums.copy(), or build a new list with a comprehension. Each produces a separate list object, so assigning to its indices leaves the original untouched. The elements themselves are still shared, which is harmless for immutable values like integers.
Why can a tuple not be changed but a list can?
A tuple is an immutable object, so its contents are fixed once created and any apparent change produces a new tuple. A list is mutable by design, which makes it suitable for data you update step by step, such as results filled in by a loop.
Exam move
For every list exercise, sketch a names-and-objects diagram before running code, then use is in the shell to check whether your arrows were right. Rewrite one function that mutates its parameter into a version that copies first, and confirm with a print that the caller's list survives.
Working through Objects and Mutable Sequences in CS1010E? Sia is AskSia’s AI Computer Science tutor — ask any CS1010E Objects and Mutable Sequences question and get a clear, step-by-step explanation grounded in how CS1010E is taught and assessed. Read this chapter free, then take your hardest questions to Sia.