What do you suppose will the following program display?
a = 1
b = a
b = 0
print(a)
The first line sets a
to 1, the second copies that 1
into b
, the third sets b
to 0, and the fourth
displays a
. At this point, a
is still 1: When we
executed the statement “b = a
”, the value of
a
is copied into b
, but Python forgets any link to
a
beyond that, so the later change to b
doesn't
alter a
. So this short program displays the value 1.
The following program ends up being essentially equivalent:
def set_to_zero(b): # (Function's name is misleading!)
b = 0
a = 1
set_to_zero(a)
print(a)
When we call “set_to_zero(a)
”,
again, the value of a
— that is, 1 — is copied
into the parameter variable b
. Just as before, no
long-term link between b
and a
exists, so the
assignment to b
within set_to_zero
only changes
b
, not a
. Once we return from set_to_zero
,
then, we end up displaying the current value of a
, which
is still 1.
(Despite its name, the set_to_zero
function
is completely pointless: All it does is set the value of its
parameter variable, a variable that is promptly lost as soon as
we return from the function.)
Now let's look at another little program.
a = [1, 2, 3]
b = a
b[0] = 0
print(a[0])
This program behaves very differently:
Variables don't hold lists in the same sense that they hold numbers.
After all, the “box” corresponding to a variable has
a fixed size, whereas a list often takes up a large amount of memory.
Instead, a variable actually holds a reference to
a list. We can diagram this with a picture, using an arrow
in a
's box pointing to the list.
In the assignment statement “b = a
”, we
copy the contents of a
's “box” into b
's
“box”. In this case, a
's box just contains
an arrow, so an arrow to the same location is placed in b
's
box.
Once you see this picture of a
and b
both
referencing the same list, you naturally expect that the line
&lqduo;b[0] = 0
” to change that shared list.
Consequently, in displaying a[0]
, we will end up
displaying the value 0.
Looking at the following program, then, you will naturally expect the behavior to be the same as before.
def set_to_zero(b):
b[0] = 0
a = [1, 2, 3]
set_to_zero(a)
print(a[0])
In calling “set_to_zero(a)
”, Python will
make b
reference the same list as a
does.
Then set_to_zero
alters the contents of that list
before returning, so that a[0]
will end up being 0.
Suppose, however, we had written the following.
def set_to_zero(b):
b = [0, 2, 3]
a = [1, 2, 3]
set_to_zero(a)
print(a[0])
This is entirely different. Rather than change the list
that b
is referencing, the line
“b = [0, 2, 3]
” leads b
to reference another
list altogether.
(after
a = [1, 2, 3]
)
(after entering
set_to_zero(a)
)
(after
b = [0, 2, 3])
Consequently, in displaying a[0]
, this program ends
up displaying 1.