Concepts / Aliasing and References in Python

Aliasing and References in Python

Aliasing becomes important when more than one variable name refers to the same mutable list.

  • Programming
Interactive lab

Try it: Names and Objects

How Python variables are names bound to objects: assignment never copies, mutating a list is seen through every name that points at it, and ints are replaced rather than changed.

How it works

  1. name = object binds a name; b = a makes b point at the same object.
  2. Mutating a list (append, +=) changes the one shared object.
  3. a = a + [x] and y = y + 1 create NEW objects and re-point one name.
  4. Passing a list to a function passes the reference, so the function can change it.

Default run (7 steps): Two names, one list. Every name is a label that points at an object. … Printed: [1, 2, 3] / True

Simplified: Six fixed scripts on a tiny heap; you choose the values. Object numbers are illustrative, not real id() values.

Educational simulation

Loading the simulation…

The Shared-Collection Problem

Lists and tuples both hold ordered collections of related values, but they support different programming decisions. A list is mutable, so its elements can be added, removed, or changed after creation. A tuple is immutable, so its contents are fixed. The important question is not which type is universally better. The question is whether later code should be allowed to change the collection.

Aliasing becomes important when more than one variable name refers to the same mutable list. If the list is changed through one name, code using another name can observe the changed collection. This flexibility is useful when shared updates are intentional, but it can also create aliasing bugs when a function or part of a program changes data unexpectedly.

first_nameMutable listshared collectionsecond_namerefers torefers to
What happens when two variable names refer to the same mutable list and one name changes it?

Tracing a Mutation

What do you think happens?

Suppose two names refer to one mutable list. If the list is changed through the first name, what should the second name observe?

  • The second name observes the changed list

  • The second name keeps an independent unchanged list

  • The operation is impossible because lists cannot change

Reveal answer
Answer:

The second name observes the changed list.

Both names refer to the same mutable list in this example. Mutating that shared collection changes the state visible through either name.

Worked example

A Shared List After an Update

Two parts of a program use the same list of tasks. One part adds a new task. What should the other part see?

  1. 1
    Initial state

    Both names refer to the same mutable collection of tasks.

  2. 2
    Mutation

    The first part adds an item to the list. Adding an item is one of the changes that lists support after creation.

  3. 3
    Observation

    The second part sees the added item because it also refers to that shared list.

  4. 4
    Design check

    This behavior is appropriate when both parts are meant to share updates. It is a liability when the second part was expected to receive protected, unchangeable data.

Result

Use a mutable list when shared changes are intentional; avoid exposing shared mutable state when accidental changes would be difficult to debug.

first_nameitems A, Bfirst_nameitems A, B, Csecond_nameitems A, Bsecond_nameitems A, B, Csame shared listsame shared list
What changes when one reference mutates a shared list, and which references observe the result?

When Lists Fit

Lists are the default choice for most tasks because they are flexible. Choose a list when a collection must grow, shrink, or have individual elements changed after creation. The source material identifies building a collection of user inputs, accumulating results in a loop, filtering data, and sorting in place as situations where list mutability is useful.

Task constraintBetter sequence choiceReason
The collection must grow or shrinkListLists can have elements added or removed after creation.
Elements must be changed during processingListLists allow elements to be changed after creation.
The collection should remain fixedTupleTuples are immutable.
The collection must be used as a dictionary keyTupleDictionaries require immutable keys.
A function should not modify the original dataTuplePassing a tuple guarantees that the function cannot modify the original data.

Choose according to the collection's required behavior, not by habit.

Three Reasons to Choose Tuples

Tuples are not merely lists with a different appearance. Their immutability solves three specific problems. First, tuples must be used as dictionary keys because dictionaries require immutable keys. Second, tuples provide cleaner syntax for returning multiple values from a function. Third, passing a tuple to a function guarantees that the function cannot modify the original data, which prevents a class of aliasing bugs.

Worked example

Matching the Type to the Constraint

Select a list or tuple for each situation: a fixed group of related values, a collection that must accept new items, a dictionary key, a function input that must not be modified, and a function result containing multiple values.

  1. 1
    Fixed group

    Choose a tuple because the group is not intended to change.

  2. 2
    Growing collection

    Choose a list because the task requires adding items.

  3. 3
    Dictionary key

    Choose a tuple because dictionary keys must be immutable.

  4. 4
    Protected function input

    Choose a tuple because the called function cannot modify the original tuple data.

  5. 5
    Multiple returned values

    Choose a tuple when the fixed group of returned values benefits from tuple return syntax.

Result

Tuples are preferable when fixed structure, dictionary-key use, clean multi-value returns, or protection against modification is the important constraint. Lists are preferable when the collection must change.

Listmutable; can changeGrowing collectionTupleimmutable; fixedDictionary keysupportssupports
Which sequence communicates flexibility, and which communicates a fixed protected collection?

Selecting Under Constraints

Sequence taskMust change?add, remove, or changeitemsListmutable and flexibleMust stay fixed?protect from modificationTupleimmutableevaluateyesnoyesno, if key or protected input is required
How should mutation, fixed structure, safe sharing, and dictionary-key requirements guide the choice?
MEDIUM

For each task, choose list or tuple and explain the constraint that determines your choice: a collection of user inputs that will grow; a fixed group of related values; a dictionary key; a function input that must not be modified; and a collection that will be filtered and sorted in place.

Hints
  • Ask whether the collection must change after creation.
  • Remember that dictionary keys must be immutable.
  • A tuple can prevent a function from modifying the original data.
  • Common mistake

    Choosing a list automatically for every ordered collection

    What it looks like

    Using a mutable list for data that should remain fixed or protected from a function

    Why it fails

    The collection can be changed even though the task does not require mutation, increasing the risk of aliasing bugs.

    Do this instead

    Choose a tuple when immutability provides a real benefit.

  • Common mistake

    Choosing a tuple when the task requires additions or removals

    What it looks like

    Representing a collection that must grow as a tuple

    Why it fails

    Tuples are immutable and are not the appropriate tool for a collection that must change.

    Do this instead

    Choose a list when the collection must grow, shrink, or have elements changed.

  • Common mistake

    Trying to use a list as a dictionary key

    What it looks like

    Selecting a list to represent a key made from multiple related values

    Why it fails

    Dictionaries require immutable keys.

    Do this instead

    Use a tuple for a dictionary key.

  • Common mistake

    Ignoring shared mutable state

    What it looks like

    Passing a mutable list through code when the receiving function should not change the original data

    Why it fails

    Shared mutable data can lead to aliasing bugs.

    Do this instead

    Pass a tuple when the function must be unable to modify the original data.

Deliberate Sequence Choices

  1. 1
    A list is mutable and is the default choice for most tasks.
  2. 2
    Aliasing occurs when multiple names refer to shared mutable data, so a mutation through one name can affect what another name observes.
  3. 3
    Choose a tuple when the collection should remain fixed or when a function must be unable to modify the original data.
  4. 4
    Tuples must be used as dictionary keys because dictionaries require immutable keys.
  5. 5
    Tuples also provide cleaner syntax for returning multiple values from a function.

Key Takeaways

  • Use a list when a collection must be added to, reduced, or changed.
  • Treat mutability as a liability when shared data should not be altered accidentally.
  • Use a tuple for fixed data, dictionary keys, protected function inputs, and clean multiple-value returns.
  • Make the sequence choice from the task's constraints rather than choosing by habit.

Related concepts

More concepts starting with A