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

AltStyle によって変換されたページ (->オリジナル) /