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