[Tutor] Not understanding a bit of code behavior

Steven D'Aprano steve at pearwood.info
Tue Jan 25 14:45:40 CET 2011


Bill Allen wrote:
> Ok, I have definately verified this to myself.   The following works
> perfectly and is a little easier to understand.  In this version, I am
> plainly modifying my parts_list iterator thus producing the effect of an
> iterator that is growing over the course of the operation of the code.  So,
> I am convinced that I had previously assigned part_list to out_list by
> reference, not value as I mistaken thought when I first wrote the code,

I believe you're working under a misunderstanding there. Python is 
neither by reference nor value, if I've understood what you mean by 
that. (Normally people talk about "by reference" when discussing calling 
functions, not assignment, so I may have misunderstood you.)

After executing the line `out_list = part_list`, *both* of these 
statements are *incorrect*:

"out_list is a copy of part_list"  +++ WRONG +++
"out_list and part_list are the same variable (out_list is an alias for 
part_list)"  +++ ALSO WRONG +++

In a nutshell, Python uses the *name binding* assignment model. When you 
do this:

part_list = [1, 2]

Python creates a *name* "part_list" and binds it to the *object* [1, 2]. 
Then when you do this:

out_list = part_list

the name "out_list" is created and bound to the same object as 
part_list. This means that out_list and part_list are two names for the 
same object, but this is not a permanent state of affairs -- they happen 
to be bound to the same object now, but you can re-bind one without 
changing the other.

A month or so ago, somebody raised a similar question about pass by 
reference and pass by value. If you will excuse me blowing my own 
trumpet, I think my response then may be useful for you now:

http://www.mail-archive.com/tutor%40python.org/msg46612.html

To use a copy of part_list, you need to explicitly copy it. For lists, 
the easiest way is with a slice:

out_list = part_list[:]

You can also use the copy module, and functions copy.copy and 
copy.deepcopy, to copy other objects.


> which explains it.  It was a silly mistake born from still being new in
> Python and thinking in terms of another language I know that typically
> assigns by value instead.  It had no occurred to me initially that it was
> possible to modify an iterator in this way.  I do not think most languages
> would allow this.

My understanding is that this behaviour -- multiple names for one object 
-- is standard semantics for most modern languages, including Perl, 
Ruby, Java, and many others.




-- 
Steven


More information about the Tutor mailing list