1

I have a list of class instances, and I want to append separate items to an attribute for each. However, I ended up appending each item to the attribute on every instance in the list. Example code below:

class example:
    def __init__(self):
        example.xlist = []

classes = [example(), example(), example()]
i=0
for instnce in classes:
    instnce.xlist.append(i)
    i+=1
print("1st list:", classes[0].xlist)
print("2nd list:", classes[1].xlist)
print("3rd list:", classes[2].xlist) 

I want the output to be:

1st list: [0]  
2nd list: [1]  
3rd list: [2]

but instead I get:

1st list: [0, 1, 2]  
2nd list: [0, 1, 2]  
3rd list: [0, 1, 2]

any ideas on what is happening / what I can change to get the desired output?

2
  • 3
    You should assign self.xlist, not example.xlist, in the __init__() method. example.xlist is shared by all instances. Commented Apr 7, 2022 at 20:07
  • Your __init__() method should contain: self.xlist = []. The code you have keeps assigning a new empty list to the one class attribute and so the call to append() operates on that one list. Commented Apr 7, 2022 at 20:07

1 Answer 1

1

The problem is in your constructor when you create the new list. Instead of creating example.xlist, you should try using self.xlist instead. In Python, the self keyword, refers to the specific instance and not the general object.

If we apply this change to your sample code, we get:

class example:
    def __init__(self):
        self.xlist = []

classes = [example(), example(), example()]
i=0
for instnce in classes:
    instnce.xlist.append(i)
    i+=1
print("1st list:", classes[0].xlist)
print("2nd list:", classes[1].xlist)
print("3rd list:", classes[2].xlist) 

This code produces the correct output.

Sign up to request clarification or add additional context in comments.

4 Comments

Note that self isn't a keyword, but only the conventional name we give to the first parameter of the methods, which will receive the instance as first argument. Also, __init__ isn't really a constructor, see stackoverflow.com/questions/28791639/initializer-vs-constructor .
Whoops, that was a typo just in my example code, though your changes do solve that. My actual code gives the attribute a default value, like this: class example: def __init__(self,xl=[]): self.xlist = xl That seems to be causing my issues, perhaps because the same blank list gets assigned to each?
Got it! Could you please edit your question to fix the typo in your code so that someone can answer it fully instead of as a comment that might not be visible?
But to answer your question, you should use self.xlist = xl.copy() instead to create a new instance of a list that has the same value.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.