dave em <daveandem2...@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 -- https://mail.python.org/mailman/listinfo/python-list