A question on modification of a list via a function invocation
Cameron Simpson
cs at cskk.id.au
Wed Aug 16 18:26:35 EDT 2017
On 16Aug2017 23:06, Mok-Kong Shen <mok-kong.shen at t-online.de> wrote:
>Am 15.08.2017 um 20:47 schrieb Larry Hudson:
>[snip]
>>>=============== test2() code ==============
>>>def test2(alist): ss ─┬─> [1, 2, 3]
>>> alist ─┘
>>>---------------------------------------------
>>> <assignment> ss ─┬─> [3, 6, 9]
>>> alist ─┘
>>>---------------------------------------------
>>> alist = [30, 60, 90] ss ───> [3, 6, 9]
>>> alist ───> [30, 60, 90]
>[snip]
>
>The above shows that with <assignment>, i.e. assigning single values to
>individual members of alist (with alist[0]=3 etc.) is "principally"
>different from assigning a whole list to alist (with alist=[30,60,90]).
>The first operation doesn't affect the connection between ss and alist,
>while the second separates the connection between ss and alist, as your
>diagram above clearly indicates.
>
>Isn't this kind of convention/rule something that appears to be not
>quite natural/"logical" to the common users (non-experts)?
Well, it may not seem natural, but it is consistent. Larry's excellent diagrams
have glossed over the lower level of array assignment for clarity.
Observe:
alist = [1,2,3]
This causes "alist" to refer to the list object [1,2,3]. But a list is itself a
compound object with references to its elements. So where Larry drew:
alist ───> [1,2,3]
a more complete diagram looks like this:
alist ───> [ ───> 0,
───> 1,
───> 2
]
so that when you write:
alist[1] = 9
You're dropped the reference to the value 1, and replaced it with a reference
to the value 9:
alist ───> [ ───> 0,
───> 9,
───> 2
]
So you can see that "alist" is a variable name - all python variables are
references to values. So "alist[1]" is also effectively a variable name. What
one would call an "lvalue" in the C programming language: a term that may
appear on the left of an assignment statement.
So they are not funcamentally different activity - what has changed is how you
describe the reference which is being modified.
Consider an object:
class C:
def __init__(self, v0):
self.x = v0
o = C(1)
o2 = C(9)
o.x = 9
o = o2
Here we've made an object with an attribute "x". We make a first instance with
x=1, _bound_ to the name "o". We make another with x=9, bound to the name "o2".
Then:
o.x = 9
changes the reference within the first object to refer to the value 9 instead
of the value 1. It does not change what the name "o" refers to.
Versus:
o = o2
which changes which object the name "o" refers to ("is bound to"): it now
refers to the second object we made.
This is exactly analogous to the array example, but using objects. The notation
eg "alist[1]" or "o.x" is just what you need to say to designate which
reference you are changing.
Cheers,
Cameron Simpson <cs at cskk.id.au> (formerly cs at zip.com.au)
More information about the Python-list
mailing list