0

I am creating a class that has a list of a second object and a total of the amount value from the second object. This in itself works. However I need to group them by category so I created a dictionary of them. Which seems simple however whenever I append an object to a list it appends to all of the lists in the dictionary.

class objA:
    amount = 0
    listBs = []
    category = ""
    def __init__(self,category):
        self.category = category
class objB:
    amount = 0
    category = ""
    otherproperty = ""

mydict = {}

b1 = objB()
b1.amount = 1
b1.category = "foo"
b1.otherproperty = "abc"

if(b1.category not in mydict.keys()):
    mydict[b1.category] = objA(b1.category)
mydict[b1.category].listBs.append(b1)
mydict[b1.category].amount += b1.amount


b2 = objB()
b2.amount = 2
b2.category = "bar"
b2.otherproperty = "xyz"

if(b2.category not in mydict.keys()):
    mydict[b2.category] = objA(b2.category)
mydict[b2.category].listBs.append(b2)
mydict[b2.category].amount += b2.amount

print("foo amount: " + str(mydict["foo"].amount) + " - foo len: " + str(len(mydict["foo"].listBs)))
print("bar amount: " + str(mydict["bar"].amount) + " - bar len: " + str(len(mydict["bar"].listBs)))

when I run the above code I get the expected amount of 1 for foo and 2 for bar but both lists have a len of 2 since they both contain b1 and b2.

I took the class objects out and the same pricipal works just appending to a dict of lists so the following works

dictoflists = {}
dictoflists["key1"] = []
dictoflists["key1"].append("k1v1")
dictoflists["key2"] = []
dictoflists["key2"].append("k2v1")
dictoflists["key2"].append("k2v2")
print(dictoflists)

output:

{'key1': ['k1v1'], 'key2': ['k2v1', 'k2v2']}

Is there a way to get this to work or a better solution?

2
  • objA.listBs has been defined on the class itself. Every time you reference listBs from any instance of objA it will be a reference to the same list Commented Dec 29, 2019 at 5:38
  • @IainShelvington How do I achieve the desired behavior giving each instance of objA it's own listBs? Is there some other way to define it that I'm not aware of? Commented Dec 29, 2019 at 6:21

2 Answers 2

1

Change the definition of the objA class so that the variables are defined pre-instance instead of on the class itself

class objA:
    def __init__(self, category):
        self.category = category
        self.amount = 0
        self.listBs = []
Sign up to request clarification or add additional context in comments.

1 Comment

I just realized I forgot to mark this as the correct answer. Thank you for your help.
1

So, I have initialized the variable inside constructor -

class objA:
        amount = 0

        category = ""
        def __init__(self,category):
            self.category = category
      #Initialize the variable inside constructor     
            self.listBs = []
class objB:
    amount = 0
    category = ""
    otherproperty = ""

mydict = {}

b1 = objB()
b1.amount = 1
b1.category = "foo"
b1.otherproperty = "abc"

if(b1.category not in mydict.keys()):
    mydict[b1.category] = objA(b1.category)
mydict[b1.category].listBs.append(b1)
mydict[b1.category].amount += b1.amount


b2 = objB()
b2.amount = 2
b2.category = "bar"
b2.otherproperty = "xyz"

if(b2.category not in mydict.keys()):
    mydict[b2.category] = objA(b2.category)
mydict[b2.category].listBs.append(b2)
mydict[b2.category].amount += b2.amount

print("foo amount: " + str(mydict["foo"].amount) + " - foo len: " + str(len(mydict["foo"].listBs)))
print("bar amount: " + str(mydict["bar"].amount) + " - bar len: " + str(len(mydict["bar"].listBs)))

Comments

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.