[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