Majid khalili
Majid khalili

Reputation: 520

Appending an item to a element of a list, adds it to all of the elements in the list in Python?

I have two Classes Cars and CarCategory and in the CarCategory there is a list of Cars. The classes are defined as below:

class Car:
    Name     = None
    def __init__(self, name):
        self.Name = name

class CarCategory:
    Category = None    
    lstCars = []
    def __init__(self, name):
        self.Cateogory = name

Then I defined a list of CarCategories as below:

lstCategories = []

tmpcat = CarCategory('SUV')
lstCategories.append(tmpcat)

tmpcat = CarCategory('MPV')
lstCategories.append(tmpcat)

Now, I am supposed to add list if cars into these categories, and I do it as bellow:

tmpCar = Car('X3')
lstCategories[0].lstCars.append(tmpCar)

The problem is that while doing this, the tmpCar is added to list of cars in both categories, i.e. it is added to both lstCategories[0] and lstCategories[1].

I am using, Spyeder and Python 3.7.

PS: I know this might not be the best way, and it is better to have Category property in Car class, but I need to do it like this.

Upvotes: 1

Views: 70

Answers (3)

Subham
Subham

Reputation: 411

Basically I found this and used it

import dataclasses 

@dataclasses.dataclass 
class Car:
    Name : str 

@dataclasses.dataclass
class CarCategory:
    Category : str
    lstCars: list = dataclasses.field(default_factory=list)
     

    
    def add(self, car):
        self.lstCars.append(car) 
        return self 


lstCategories = []

tmpcat = CarCategory('SUV')
lstCategories.append(tmpcat)


tmpcat = CarCategory('MPV')
lstCategories.append(tmpcat)

tmpCar = Car('X3')

# using `add method`
lstCategories[0].add(tmpCar)
print(lstCategories[0].lstCars)
print(lstCategories[1].lstCars)

gives,

[Car(Name='X3')]
[]

[Program finished]

Upvotes: 0

Kyzyl Monteiro
Kyzyl Monteiro

Reputation: 71

Concept explained and discussed in this answer.

Upvotes: 0

Nikos M.
Nikos M.

Reputation: 8345

Your lstCars in category is static thus shared by all instances. You should make it instance-based not class-based, like below:

class Car:
    def __init__(self, name):
        self.Name = name # property of instance

class CarCategory:
    def __init__(self, name):
        self.lstCars = [] # property of instance
        self.Category = name # property of instance

    # optionally you can add an `add` method to add cars to categories
    def add(self, car):
        self.lstCars.append(car) # append to THIS instance 
        return self # make it chainable

# now try
lstCategories = []

tmpcat = CarCategory('SUV')
lstCategories.append(tmpcat)

tmpcat = CarCategory('MPV')
lstCategories.append(tmpcat)

tmpCar = Car('X3')
# using `add method`
lstCategories[0].add(tmpCar)
print(lstCategories[0].lstCars)
print(lstCategories[1].lstCars)

check online

Upvotes: 3

Related Questions