Concepts / Function Arguments and Object Modification

Function Arguments and Object Modification

Variables are references to objects in memory, not the objects themselves.

  • 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-List Puzzle

Suppose two variable names refer to one list. If the list changes through one name, should the other name show the change? The answer is yes. The key is to stop thinking of a variable as the object itself. A variable is a reference to an object in memory. When several variables refer to the same object, they provide several ways to reach that one object.

What do you think happens?

A list is associated with two variable names. The list is changed through the first name. What will the second name show?

  • The original list, without the change

  • The changed list

  • A completely unrelated value

Reveal answer
Answer:

The changed list

Both names refer to the same object, so a change made through one reference is visible through the other.

first_nameshared list[item, item]second_namerefers torefers to
What object does each variable refer to, and how are multiple variable names connected to the same object?

Tracing a Shared Reference

Object binding is the connection between a variable name and an object. Assigning another variable name to an existing list gives that second name another reference to the same list; it does not create an independent list. Therefore, a modification made through either name changes the one shared object. Every variable that refers to that object then reveals the changed contents.

Worked example

Two Names Following One Change

Imagine that basket and second_basket both refer to one list containing the items apple and bread. The item cheese is added through basket. What does second_basket refer to afterward?

  1. 1
    1. Identify the object

    There is one list object containing apple and bread. Both variable names refer to that same object.

  2. 2
    2. Apply the change

    The list is modified through basket, so the shared list now also contains cheese.

  3. 3
    3. Follow the other reference

    second_basket still refers to the same list object. It therefore shows the list containing apple, bread, and cheese.

Result

Both variable names reveal the modified shared list.

basketshared list[apple, bread]basketshared list[apple, bread, cheese]second_basketsecond_basketrefers torefers torefers torefers to
What happens to every variable pointing to a list when the list is modified through one of those variables?

Arguments Follow References

A function argument follows the same reference idea. When a list is passed to a function, the function parameter refers to the list object supplied by the caller. If the function modifies that list, the caller's variable refers to the modified object afterward. The important question is not only which parameter name is used, but which object that name refers to.

Worked example

Following a List Through a Function

A caller has a list containing red and blue and passes it to a function. Inside the function, the list is modified by adding green. What does the caller's variable refer to after the function finishes?

  1. 1
    1. Start with the caller

    The caller's variable refers to one list object containing red and blue.

  2. 2
    2. Bind the parameter

    The function parameter refers to that same list object while the function runs.

  3. 3
    3. Modify the object

    The function changes the shared list by adding green.

  4. 4
    4. Return to the caller

    The caller's variable still refers to the same list object, now containing red, blue, and green.

Result

A function can modify the caller's list when its parameter refers to that same list object.

caller list[red, blue]function parametersame list objectadd greencaller list[red, blue, green]passed tomodified throughvisible in
When a list is passed to a function, what does the parameter refer to, and what happens to the caller's list if the function modifies it?

Making an Independent Copy

When two variable names must refer to independent lists, create a copy rather than assigning another name to the existing list. Full slice notation creates an independent copy. The notation uses the entire list, as in mylist = shoplist[:]. After this operation, shoplist and mylist refer to separate list objects. A modification to one list does not become a modification to the other list through shared reference.

Worked example

Separating Two Lists

shoplist refers to a list containing notebook and pen. Create an independent list for mylist using full slice notation, then add folder to mylist. What should happen to shoplist?

  1. 1
    1. Begin with one list

    shoplist refers to the original list containing notebook and pen.

  2. 2
    2. Copy the full list

    mylist = shoplist[:] creates an independent copy of the list.

  3. 3
    3. Modify the copy

    Adding folder to mylist changes the copied list.

  4. 4
    4. Check the original

    shoplist still refers to the original list, so it remains notebook and pen.

Result

mylist contains notebook, pen, and folder, while shoplist remains notebook and pen.

shoplistoriginal list[notebook, pen]mylistindependent copy[notebook, pen]refers torefers tofull slice creates
How does full slicing create a new list object, and which variables point to the original versus the copy?
OperationReferencesEffect of modifying one list
Assign another name to the existing listBoth names refer to the same objectThe change is visible through both names
Use full slice notationThe original name and new name refer to separate list objectsThe change to one list does not change the other list through shared reference

The essential difference between sharing a list and copying a list.

Mistakes with Shared Objects

  • Common mistake

    Assuming that a second variable automatically creates a new list

    What it looks like

    Two variable names are associated with the same existing list, and the list is modified through one name.

    Why it fails

    Multiple variables can point to one object. A second name does not by itself make the object independent.

    Do this instead

    Use full slice notation when an independent list copy is required.

  • Common mistake

    Looking only at the variable name instead of the referenced object

    What it looks like

    A function parameter has a different name from the caller's variable, so the parameter is treated as unrelated.

    Why it fails

    The parameter can refer to the same list object supplied by the caller.

    Do this instead

    Trace which object each variable or parameter refers to before predicting the result.

  • Common mistake

    Treating an unexpected change in another variable as random behavior

    What it looks like

    A list changes through one variable, and the same change appears through another variable.

    Why it fails

    Both variables may refer to the same object.

    Do this instead

    Check for shared references before searching for a different cause.

Edge case

The important distinction is whether the list object is shared or independently copied. If several variables refer to one list, a modification is shared. If full slice notation has created an independent copy, modifying that copy does not modify the original list through shared reference.

Reference Tracking Practice

MEDIUM

For each situation, identify whether the variables refer to one shared list or to independent lists. Then predict which list shows the modification: two names refer to one list and the list is changed through the first name; a list is copied with full slice notation and the copy is changed; a list is passed to a function and the function modifies the list.

Hints
  • Start by identifying the list object, not just the variable names.
  • A second reference to an existing list is still connected to that same object.
  • Full slice notation creates an independent copy.
  • One object can have multiple variable names referring to it.
  • A modification through one reference is visible through every reference to that same object.
  • A function parameter can refer to the list supplied by the caller.
  • Full slice notation, such as mylist = shoplist[:], creates an independent list copy.
  • Tracing object references helps prevent unexpected modifications in multiple places.

Key Takeaways

  • Variables are references to objects in memory, not the objects themselves.
  • Multiple variables can refer to one list, so modifying the list through one variable affects what the others reveal.
  • A function parameter can refer to the same list object that the caller supplied.
  • Use full slice notation, such as mylist = shoplist[:], to create an independent list copy.
  • Reference tracking helps prevent unexpected modifications from appearing in multiple places.

Related concepts

More concepts starting with F