[Tutor] Scope and values in a list

Mallett, Roger rmallett@rational.com
Tue, 26 Dec 2000 08:49:33 -0800


Remco,

Alright, being that 
> When you do "myList = newList", 
> that old list isn't changed at 
> all, rather myList now refers to
> a new list.

AND being that: "since everything in Python is a reference, and the variable
doesn't hold any value but is a name for an object", 

then why does x display its newly assigned value (10...19) once the *for*
loop has complete (see output below)?  Seems that myList does indeed take on
the new value, but that the "i" in the *for* loop is using a snapshot of the
myList object to iterate (and not actually using myList).  Is that true?

I appreciate the response you gave, it was very helpful.  The problem has
bothering me for a couple of days as I've been attempting to figure it out
without writing a hack.

Now that I know exactly what is happening, I can create a proper fix.

>>> x = range(10)
>>> for i in x:
... 	x = range(10,20)
... 	print i,
... 	
0 1 2 3 4 5 6 7 8 9
>>> x
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> 


Roger Mallett

-----Original Message-----
From: Remco Gerlich [mailto:scarblac@pino.selwerd.nl]
Sent: Saturday, December 23, 2000 12:16 AM
To: Mallett, Roger
Subject: Re: [Tutor] Scope and values in a list


On Fri, Dec 22, 2000 at 04:18:23PM -0800, Mallett, Roger wrote:
> I am having problems with a *for* loop picking up the *modified* value of
a
> list and would therefore like some to better understand SCOPE.
> 
> My basic problem is 
> 
> 
> for n in myList:
> 	...
> 			then in a deeply nested *if*
> 				I modified the values of the list:  myList =
> newList
> 
> The change to the list consists of eliminating some elements from the list
> 
> Looking at the STACK VIEW, I can observe the modifications taking place to
> the list; however, when the loop comes back around and *n* is assigned a
new
> value it still seems to have access to the original list.

The for loop looks up myList at the start of the loop, and starts looping
over the list that it refers to at that moment. When you do "myList =
newList", that old list isn't changed at all, rather myList now refers to
a new list. So the for loop shouldn't be influenced by that.

So

>>> x = range(10)
>>> for i in x:
...   x = range(10,20)
...   print i

Simply prints 0 to 9. Keep in mind that everything is a reference in Python;
a variable doesn't hold any value but is a name for an object instead. The
for
loop uses the name to lookup the object at its start, then doesn't care
about the name anymore.

So that explains this effect. However, it is a BAD IDEA to change the list
you are looping over in a for loop even if it did work. For instance, you
could delete items in the list, or make it larger, and the way the for loop
behaves is UNDEFINED. Don't do it. Instead, make a new list, put your 
results in that, and copy it back into myList after the loop.

I hope this helps. If you still have trouble, show us what you're doing :)

-- 
Remco Gerlich