Explanation of list reference

Marko Rauhamaa marko at pacujo.net
Fri Feb 14 14:56:07 EST 2014


dave em <daveandem2000 at gmail.com>:

> Case 1: Example of variable with a specific value from P 170 of IYOCGWP
>
>>>> spam = 42
>>>> cheese = spam
>>>> spam = 100
>>>> spam
> 100
>>>> cheese
> 42
>
> Case 2: Example of variable with a list reference from p 170
>
>>>> spam = [0, 1, 2, 3, 4, 5]
>>>> cheese = spam
>>>> cheese[1] = 'Hello!'
>>>> spam
> [0, 'Hello!', 2, 3, 4, 5]
>>>> cheese
> [0, 'Hello!', 2, 3, 4, 5]
>
> What I am trying to explain is this, why in case 1 when acting on spam
> (changing the value from 42 to 100) only affects spam and not cheese.
> Meanwhile, in case two acting on cheese also affects spam.

A very good question! Elementary and advanced at the same time.

There are two fundamentally different kinds of values in Python: "small"
values and "big" values. A variable can only hold a small value. A list
element can only hold a small value. A dictionary entry can only hold a
small value. The same is true for an object member (aka field).

So we have four kinds of (memory) slots: variables, list elements,
dictionary entries and fields. Any slot can only hold a small value.

The small values include numbers, booleans (True or False) and
references. All other values are big, too big to fit in a slot. They
have to be stored in a "vault" big enough to hold them. This vault is
called the heap. Big values cannot be stored in slots directly; instead,
references to big values are used.

Let me now annotate your excellent example:

  spam = 42       # put the small value 42 (number) in a memory slot,
                  # namely a variable named "spam"

  cheese = spam   # copy the contents of the variable "spam" into
                  # another memory slot, a variable named "cheese;"
                  # now both variables contain the same small value 42

  spam = 100      # replace the contents of the variable "spam" with the
                  # small value 100; leave the contents of the variable
                  # "cheese" intact

  spam
  > 100           # as expected

  cheese
  > 42            # ditto


  spam = [0, 1, 2, 3, 4, 5]
                  # a list is a "big" value; the statement creates a
                  # list of six slots in the heap an puts a number in
                  # each slot; then, a reference to the list is placed
                  # in the variable "spam"

  cheese = spam   # copy the reference to the six-element list from the
                  # variable "spam" into the variable "cheese;" the heap
                  # still contains only one list, and the two variables
                  # refer to the same one

                  # (rationale: big values take time and space to copy
                  # in full, and almost always copying references is
                  # good for the problem at hand; if a full copy is
                  # needed, Python has ways to do that, too)

  cheese[1] = 'Hello!'
                  # a character string (text snippet) is a "big" value;
                  # the statement creates the six-character string
                  # 'Hello!' in the heap; then, a reference to the
                  # string is placed in the second element of the list
                  # referred to by the variable "cheese"

                  # (that's a complicated sentence with lots to chew
                  # even though the Python statement looks so innocently
                  # simple)

                  # there still is a single list in the heap; the list
                  # is still referred to by both variables; however the
                  # second slot of the list, which used to hold the
                  # number 1, has been replaced with a reference to the
                  # "big" string 'Hello!'

  spam
  > [0, 'Hello!', 2, 3, 4, 5]
                  # as expected, right?

  cheese
  > [0, 'Hello!', 2, 3, 4, 5]
                  # right?


The final situation is represented by this picture of Python's memory:


     spam          cheese
    +-----+       +-----+
    |  .  |       |  .  |
    +--+--+       +--+--+
       |             |
       |             |                       VARIABLES
  = = =|= = = = = = =|= = = = = = = = = = = = = = = = = = =
       |            /                        THE HEAP
       |   ---------
       |  /
       | |
       v v
    +-----+-----+-----+-----+-----+-----+
    |  0  |  .  |  2  |  3  |  4  |  5  | a list
    +-----+--+--+-----+-----+-----+-----+
             |
             |
             |
             |
             v a string
         +--------+
         | Hello! | a string
         +--------+


Marko



More information about the Python-list mailing list