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 -- http://mail.python.org/mailman/listinfo/python-list