dictionary containing instances of classes behaving oddly

Ben Benjamin.Barker at gmail.com
Thu Dec 28 14:13:38 EST 2006


Ah - ok. In fact I simply had:

class record:
        my_list =[]
        mops=[]

        def __init__(self,mops):
                self.mops=mops

Where mops is something I pass in when i create the instance. I had
thought that then each time I created an instance of the record class
as an element of my dictionary:

self.mop_list[record_number]=record(self.mops[:])

I would create a brand new instance of the record class.It would have a
mops list initialized with mops (because the def__init__ constructor is
called when the class is instantiated), and an empty, individual list
my_list.

I could then access each individual list by doing:

self.mop_list[x].my_list[y]=something

But in fact the same my_list is being accessed for all values of x, so
a change to one list is in fact a change to them all. I think you might
be right, but can't quite work it out myself! I'll keep trying :-)

Thanks for your help,

Ben





Erik Johnson wrote:

> "Ben" <Benjamin.Barker at gmail.com> wrote in message
> news:1167326178.386764.300200 at n51g2000cwc.googlegroups.com...
>
> <snip>
>
> > This seems to work without any errors. But bizzarely I find that
> > whatever my record number, the instance of "my_class" is appended to
> > every list. So in this case
> >
> > self.mop_list[0].my_list.append(my_class(Some data for the
> > constructor))
> >
> > I would expect to append an instance of my_class to
> > self.mop_list[0].my_list
> >
> > But annoyingly
> >
> > self.mop_list[0].my_list
> > self.mop_list[3].my_list
> > self.mop_list[7].my_list
> >
> > all have an instance of my_class created and appended to them. This is
> > really confusing and quite annoying - I don't know whether anyone out
> > there can make head or tail of what I'm doing wrong?
>
> Well, it's a little bit difficult, but I think I actually know what's going
> on. You probably need some code that looks something like this, to ensure
> each object has it's own, independent list:
>
> class record:
>     def __init__(self, init_list=None):
>         self.my_list = []
>         if init_list is not None:
>             self.my_list.extend(init_list)
>
>
> Here's what I think you are doing, and below should make it clear why that
> doesn't work:
>
> class record:
>     def __init__(self, init_list=[]):
>
> That list above, the default initializer is constructed just once (when the
> def statement executes)!
>
> >>> class record:
> ...   def __init__(self, init_list=[]):
> ...     self.my_list = init_list
> ...
> >>> r1 = record()
> >>> r1.my_list
> []
> >>> r2 = record()
> >>> r2.my_list
> []
> >>> r2.my_list.append('boo!')
> >>> r1.my_list
> ['boo!']
> >>>
> >>> l1 = range(1, 4)
> >>> l1
> [1, 2, 3]
> >>> r1 = record(l1)
> >>> r2 = record(l1)
> >>> r1.my_list
> [1, 2, 3]
> >>> r2.my_list
> [1, 2, 3]
> >>> r1.my_list.append(42)
> >>> l1
> [1, 2, 3, 42]
> >>> r1.my_list
> [1, 2, 3, 42]
> >>> r2.my_list
> [1, 2, 3, 42]
> >>>




More information about the Python-list mailing list