On 9/27/10, Steven D'Aprano <st...@pearwood.info> wrote: > On Tue, 28 Sep 2010 03:54:55 am Alex Hall wrote: >> Hi again everyone, >> I have a 2d array (I guess it is technically a list) which I want to >> fill with zeros. Later I will change some values, but any I do not >> change have to be zeros. I have two complex for loops, but I tried to >> scale things down to a couple list comprehensions and I broke things. >> What is wrong with the following line? >> self.am=[[(a,b) for a in range(len(self.lines)) a=0] for b in >> range(len(self.lines)) b=0] > > > Start with a single row, of n columns: > > [0 for i in range(n)] # the loop variable i is not used > > Now all you need is to set n appropriately: > > n = len(self.lines) > [0 for i in range(n)] > > > Is there an easier way? Yes, you don't even need a list comp: > > [0]*n > > Now make m rows of the same: > > [ [0]*n for i in range(m) ] That worked, and I think I see what is going on. > > And you are done. > > > You might be tempted to take a short-cut: > > [ [0]*n ]*m > > but this doesn't work as you expect. This is one of the rare Python > gotchas -- it looks like it should work, but it doesn't behave like you > might expect. Try it and see: > >>>> a = [[0]*3]*4 >>>> a > [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]] >>>> a[0][1] = 2 >>>> a > [[0, 2, 0], [0, 2, 0], [0, 2, 0], [0, 2, 0]] > > What's going on here? It's a little complicated, so let's start with a > simpler situation: > >>>> b = [0, 0, 0] >>>> c = b # c is an alias to the same list as b >>>> d = b # so is d >>>> e = c # and e >>>> b[0] = 3 >>>> e > [3, 0, 0] > > Because both b and e refer to the same list (not copies!) any change to > b *must* also change e. It's like if Barack Obama gets a haircut, so > does the current President of the USA, because they're the same person. > > Now stick them in a list: > >>>> a = [b, c, d, e] >>>> a > [[3, 0, 0], [3, 0, 0], [3, 0, 0], [3, 0, 0]] >>>> a[0][1] = 4 >>>> a > [[3, 4, 0], [3, 4, 0], [3, 4, 0], [3, 4, 0]] > > Modify one, modify them all, because in fact they are actually all the > same list. > > [ [0]*3 ]*4 behaves the same way. There's no problem in the inner list, > but the outer list doesn't make four copies of [0,0,0], it has *one* > list repeated four times. Modify one, modify them all. That makes sense. Basically, the * operator in this case acts as a copying command. For simple data types this is fine, but throw in a complex type, in this case a list (though I expect that any object would do this) and you are just doing what Python does to copy objects: copying the memory location, not making a deep copy and getting a duplicate object. I never would have thought of that. Thanks again for the great explanation! > > > -- > Steven D'Aprano > _______________________________________________ > Tutor maillist - Tutor@python.org > To unsubscribe or change subscription options: > http://mail.python.org/mailman/listinfo/tutor >
-- Have a great day, Alex (msg sent from GMail website) mehg...@gmail.com; http://www.facebook.com/mehgcap _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor