[Tutor] initializing multiple attributes to same value

Danny Yoo dyoo@hkn.eecs.berkeley.edu
Fri, 21 Dec 2001 12:39:42 -0800 (PST)


On Thu, 20 Dec 2001, Rob McGee wrote:

> I tripped myself up on something like this:
> 
> {code}
> class Whatever:
>   def __init__(self):
>     self.one = self.two = self.three = 0
>     self.listOne = self.listTwo = []

What you're running into has more to do with the way that lists work than
member attributes.  For example:

###
>>> universities = colleges = ['berkeley', 'stanford']                  
>>> universities
['berkeley', 'stanford']
>>> colleges
['berkeley', 'stanford']
>>> universities.append('ucla')
>>> universities
['berkeley', 'stanford', 'ucla']
>>> colleges
['berkeley', 'stanford', 'ucla']
###

And you're right; the lists are being shared.  In the example above,
colleges and universites both refer to the "same" list.

It might help if we visualize variable names as ways of pointing our
fingers at a list object, sorta like this:


    colleges -------------------> ['berkeley', 'stanford', 'ucla']
                                  ^
                                  |
    universities -----------------+



What you probably want, instead, is something like this:

    colleges -------------------> ['berkeley', 'stanford', 'ucla']

    universities ---------------> ['berkeley', 'stanford', 'ucla']


That is, the two variables refer to lists that have the same stuff, but
are, nevertheless, different lists.  For that, we need to make a "copy" of
the list.

There are several ways to do this.  One way is to just hardcode it.

###
universities = ['berkeley', 'stanford', 'ucla']
colleges = ['berkeley', 'stanford', 'ucla']
###


Another way to copy lists is to take a full slice of a list:

###
universities = ['berkeley', 'stanford', 'ucla']
colleges = universities[:]
###


Don't worry if this doesn't make complete sense yet; please feel free to
ask more questions about this.  Good luck!