A question on modification of a list via a function invocation

Mok-Kong Shen mok-kong.shen at t-online.de
Wed Aug 16 20:49:23 EDT 2017


Am 17.08.2017 um 01:58 schrieb Cameron Simpson:
> On 17Aug2017 01:03, Mok-Kong Shen <mok-kong.shen at t-online.de> wrote:
>> Am 17.08.2017 um 00:39 schrieb Chris Angelico:
>>> On Thu, Aug 17, 2017 at 8:29 AM, Mok-Kong Shen
>>> <mok-kong.shen at t-online.de> wrote:
>>> Chris wrote:
>>> objects exist independently of names, and names refer to
>>> objects. If you do "x = y", you're saying "figure out which object 'y'
>>> means, and make the name 'x' refer to it". If you do "x[1] = y",
>>> you're saying "figure out which object 'y' means, and tell the object
>>> that 'x' means that it should make [1] refer to that object". So if
>>> you have multiple names referring to the same object, any change you
>>> ask that object to do will be seen by every other name that also
>>> refers to it - because it's all about the object.
>>
>> I may have misunderstood you. But I don't think what you wrote
>> above would explain why the program below produces the output:
>>
>> [1, 2, 3]
>> [3, 6, 9]
>>
>> M. K. Shen
>> -----------------------------------------------------
>>
>> def test2(alist):
>>  alist[0],alist[1],alist[2]=3,6,9
>>  alist=[30,60,90]
>>  return
> 
> This is because "alist" in the function test2 is a _local_ variable. It 
> is a reference to the same list whose reference was passed to the function.
> 
> So:
> 
>   alist[0],alist[1],alist[2]=3,6,9
> 
> This modifies the references within that list.
> 
>   alist=[30,60,90]
> 
> This makes the local name "alist" refer to a shiny new list [30,60,90], 
> totally unrelated to the list whose reference was first passed in. 
> Importantly, in the main program "ss" still refers to the original list, 
> which now has references to the values 3, 6 and 9 in it.
> 
>> def test3(alist):
>>  alist=[30,60,90]
>>  alist[0],alist[1],alist[2]=3,6,9
>>  return
> 
> This code first points "alist" to a new, unrelated, list. Then modifies 
> the references inside that list. Put different values in this function 
> (by using the same values as in test2 you can see whether changes came 
> from one or the other) eg use 5,6,7 or something.
> 
>> ss=[1,2,3]
>> test3(ss)
>> print(ss)
>> test2(ss)
>> print(ss)
> 
> So test3 first discards its reference to the [1,2,3] list, then modifies 
> an unrelate new list. So "ss" is unchanged, still holding [1,2,3].
> 
> Then test modifies the original list (affecting what "ss" holds) and 
> then points its local "alist" at something else (another shiny new 
> list). But that doesn't change what "ss" refers to, so it now has [3,6,9].

I don't yet understand. Why (by which rule of the language reference)
should "alist=[30,60,90]" mean discarding the name's reference to the
[1,2,3] list? What I conjecture is that in test2 the assignment
"alist[0], ..." can only have a proper meaning according to the syntacs
of Python if alist is meant to be the global alist. But then, since
now the name alist is known to be global, why then in the next line of
test2 the name is suddenly interpreted to be local? (Which rule of
the language reference says that?) That's what I currently continue to
wonder.

M. K. Shen

M. K. Shen
to




More information about the Python-list mailing list