[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.python

Understanding While Loop Execution

deviantbunnylord@gmail.com

2/18/2008 10:27:00 PM

Hi folks,

I'm still fairly new to programming in python and programming in
general. A friend of mine is in a CompSci 101 course and was working
on a slider game when he encountered a problem. We eventually figured
out what the problem was and built a test case to help solve it, but I
can't for the life of me figure out the why behind it. I tried
googling it and searching the list but didn't find anything that
really explained it. I'm sure it's probably just both of us
misunderstanding what the "while" statement does. So I hoped to ask
for some clarification here. So here is what we worked out was going
on with his code.

from random import shuffle

mylist=[2,1,3]
baselist=[1,2,3]
newlist=[]
count=0
while mylist!=baselist:
count+=1
shuffle(mylist)
newlist.append(mylist)
print count, mylist, newlist

Output:
>>>
1 [3, 1, 2] [[3, 1, 2]]
2 [1, 2, 3] [[1, 2, 3], [1, 2, 3]]
>>>

What he wanted was a list of lists to use later as a replay. What we
expected newlist.append(mylist) to do was to save a copy of mylist
into the collection for each iteration of the while statement.
However, what struck us as odd is that for each time the while loop
executes it changes all the lists in the list. What I found even
exasperating was if I created yet another list.

from random import shuffle

mylist=[2,1,3]
baselist=[1,2,3]
newlist=[]
saved_shufs=[]
count=0

while mylist!=baselist:
count+=1
shuffle(mylist)
newlist.append(mylist)
saved_shufs.append(newlist[0])
print count, mylist, newlist[0], saved_shufs

Output:
>>>
1 [1, 3, 2] [1, 3, 2] [[1, 3, 2]]
2 [3, 2, 1] [3, 2, 1] [[3, 2, 1], [3, 2, 1]]
3 [1, 2, 3] [1, 2, 3] [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
>>>

newlist[0] printed out correctly but when appending it into
saved_shufs it still overwrote everything.

Eventually, after plinking about I remembered that tuples were
immutable and wound up creating a variable like
tuple_of_mylist=tuple(mylist) then appending that into newlist. That
kept the list of tuples fine. I'm still wondering though what I'm not
grasping about "while" that made it do that to the lists? Or is it not
even while, is it something else I'm not getting?

Thanks in advance,
B
3 Answers

Gary Herron

2/18/2008 11:53:00 PM

0

Brad wrote:
> Hi folks,
>
> I'm still fairly new to programming in python and programming in
> general. A friend of mine is in a CompSci 101 course and was working
> on a slider game when he encountered a problem. We eventually figured
> out what the problem was and built a test case to help solve it, but I
> can't for the life of me figure out the why behind it. I tried
> googling it and searching the list but didn't find anything that
> really explained it. I'm sure it's probably just both of us
> misunderstanding what the "while" statement does. So I hoped to ask
> for some clarification here. So here is what we worked out was going
> on with his code.
>
> from random import shuffle
>
> mylist=[2,1,3]
> baselist=[1,2,3]
> newlist=[]
> count=0
> while mylist!=baselist:
> count+=1
> shuffle(mylist)
> newlist.append(mylist)
> print count, mylist, newlist
>
> Output:
>
> 1 [3, 1, 2] [[3, 1, 2]]
> 2 [1, 2, 3] [[1, 2, 3], [1, 2, 3]]
>
>
> What he wanted was a list of lists to use later as a replay. What we
> expected newlist.append(mylist) to do was to save a copy of mylist
> into the collection for each iteration of the while statement.
> However, what struck us as odd is that for each time the while loop
> executes it changes all the lists in the list. What I found even
> exasperating was if I created yet another list.
>
> from random import shuffle
>
> mylist=[2,1,3]
> baselist=[1,2,3]
> newlist=[]
> saved_shufs=[]
> count=0
>
> while mylist!=baselist:
> count+=1
> shuffle(mylist)
> newlist.append(mylist)
> saved_shufs.append(newlist[0])
> print count, mylist, newlist[0], saved_shufs
>
> Output:
>
> 1 [1, 3, 2] [1, 3, 2] [[1, 3, 2]]
> 2 [3, 2, 1] [3, 2, 1] [[3, 2, 1], [3, 2, 1]]
> 3 [1, 2, 3] [1, 2, 3] [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
>
>
> newlist[0] printed out correctly but when appending it into
> saved_shufs it still overwrote everything.
>
> Eventually, after plinking about I remembered that tuples were
> immutable and wound up creating a variable like
> tuple_of_mylist=tuple(mylist) then appending that into newlist. That
> kept the list of tuples fine. I'm still wondering though what I'm not
> grasping about "while" that made it do that to the lists? Or is it not
> even while, is it something else I'm not getting?
>
> Thanks in advance,
> B
>
First of all, it's got nothing to do with the while loop. The Python
feature that's biting you here is the fact that lists are not *copied*
when you work with them.

So in the following code, the list named full does not have 3 copies of
sub in it, but rather it has 3 *references* to the single list named
sub. Any changes to the list named sub will be reflected anywhere that
list is referred to.


>>> sub = [1,2,3]
>>> full = [sub,sub,sub]
>>> full
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
>>> sub[0] = 123
>>> full
[[123, 2, 3], [123, 2, 3], [123, 2, 3]]


So in you code, the single list mylist is shuffled each time, and
newlist keeps growing my more references to it. If you want a *copy* of
the list, you have to explicitly ask for one. The easiest way to do
that is mylist[:]. (This is a shorthand for copying out any sublist of
mylist via the syntax mylist[a:b], with a and b defaulting to whole list.)

Gary Herron



7stud --

2/19/2008 3:01:00 AM

0

On Feb 18, 4:53 pm, Gary Herron <gher...@islandtraining.com> wrote:
> Brad wrote:
> > Hi folks,
>
> > I'm still fairly new to programming in python and programming in
> > general.

a = [1, 2, 3]
b = a
print a
print b
print

a[0] = 100
print a
print b

--output:--
[1, 2, 3]
[1, 2, 3]

[100, 2, 3]
[100, 2, 3]

Tim Roberts

2/19/2008 6:21:00 AM

0

Gary Herron <gherron@islandtraining.com> wrote:
>
>So in the following code, the list named full does not have 3 copies of
>sub in it, but rather it has 3 *references* to the single list named
>sub.

Since we are being picky here, it's more accurate to say that the list
"full" contains 3 references to the list that is also referenced by the
name "sub". I've found that it is more useful to think of Python objects
(like lists) as anonymous things living out in object memory (which is, no
doubt, a happy place), and all of the names in the program just refer to
those anonymous things.

>Any changes to the list named sub will be reflected anywhere that
>list is referred to.

And vice versa. "sub" is a reference to the list, exactly like "full[0]".
No difference.

> >>> sub = [1,2,3]
> >>> full = [sub,sub,sub]
> >>> full
>[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
> >>> sub[0] = 123
> >>> full
>[[123, 2, 3], [123, 2, 3], [123, 2, 3]]

And:

>>> full[0][2] = 99
>>> sub
[123, 2, 99]
>>> full
[[123, 2, 99], [123, 2, 99], [123, 2, 99]]
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.