Как я могу назначить новые классы каждому элементу в списке, выполнив итерацию по парам ключ / значение словаря на основе соответствующего атрибута в python?

#python #list #class #dictionary #for-loop

#python #Список #класс #словарь #for-цикл

Вопрос:

Каждый существующий объект в этом списке должен быть заменен экземпляром определенного класса. У каждого существующего объекта уже есть .type, который должен соединяться с ключом в словаре для создания соответствующего класса (значение в dict). Затем объектам также необходимо восстановить их исходное .name из перед назначением класса.

Я не могу найти способ сделать это, который не включает вложенные циклы for, но вложенные циклы for в основном присваивают КАЖДОМУ члену класса одно и то же имя (последнее имя сохраняется во временной переменной).

Я изучил всю базовую литературу и понимаю фундаментальную логику, связанную с циклами, словарями и списками, я просто (уверен, что я) выполняю что-то неправильно или вкладываю что-то неправильно.

 class gameObject(object):
    def __init__(self):
        self.name = name

#Class given to any living thing in the game; confers basic stats
class livingThing(gameObject):
    def __init__(self, name="Living Thing", HP = 0):
        self.name = name
        self.HP = HP
        self.alive = True
        self.safe = True
        self.listready = False

# After livingThing, classes narrow into more specific groups that have unique traits, abilities, and roles in the game

class Animal(livingThing):
    def __init__(self):
        super().__init__()
        self.truename = ""
        self.type = ""
        self.listready = False
        self.type = "Test"
        self.truetype = ""
        self.hasatype = False


class Reptile(Animal):
    def __init__(self):
        super().__init__()
        self.therm = "ecto"
        self.type = "Game Reptile"

class Amphibian(Animal):
    def __init__(self):
        super().__init__()
        self.therm = "ecto"
        self.type = "Game Amphibian"

class Bird(Animal):
    def __init__(self):
        super().__init__()
        self.therm = "endo"
        self.type = "Game Bird"

class Mammal(Animal):
    def __init__(self):
        super().__init__()
        self.therm = "endo"
        self.type = "Game Mammal"

class Fungus(Animal):
    def __init__(self):
        super().__init__()
        self.therm = "none"
        self.type = "Game Fungus"

class Fungus(Animal):
    def __init__(self):
        super().__init__()
        self.therm = "none"
        self.type = "Game Fungus"

class Ascomycetes(Animal):
    def __init__(self):
        super().__init__()
        self.therm = "none"
        self.type = "Game Ascomycetes"

somereptile = Reptile()
somereptile.type = "Reptiles"
somereptile.name = "Some Reptile"

somefrog = Amphibian()
somefrog.type = "Amphibians"
somefrog.name = "Some frog"

somefungus = Fungus()
somefungus.type = "Fungi"
somefungus.name = "Some Fungus"

secondfrog = Amphibian()
secondfrog.type = "Amphibians"
secondfrog.name = "Second Frog"

thirdfrog = Amphibian()
thirdfrog.type = "Amphibians"
thirdfrog.name = "Third Frog"

secondfungus = Fungus()
secondfungus.type = "Fungi"
secondfungus.name = "Second Fungus"

dummypop = [somereptile, somefrog, somefungus, secondfrog, thirdfrog, secondfungus]


### PROBLEM FUNCTION ###
def givetype(poplist):
    typedict = {
    "Reptiles" : Reptile(),
    "Amphibians" : Amphibian(),
    "Birds" : Bird(),
    "Mammals" : Mammal(),
    "Fungi" : Fungus(),
    "Ascomycetes" : Ascomycetes()
    }


    holderlist = []
    tempnames = []
    i = 0

    for org in poplist:
        holderlist.append(org)
        tempnames.append(org.name)
        for key in typedict.keys():
            if (holderlist[i].type.lower() in key.lower()):
                holderlist[i] = typedict[key]
                holderlist[i].name = tempnames[i]
                print(holderlist[i].name,
                                holderlist[i].type)
                        i =1

    return holderlist


dummymaster = (givetype(dummypop))

for animal in dummymaster:
    print(animal.name, animal.type)
  

Я ожидаю, что:

 Some Reptile Game Reptile
Some Frog Game Frog
Third Frog Game Frog
Second Frog Game Frog
etc
  

Что я получаю, так это:

 Some Reptile Game Reptile
Third Frog Game Frog
Third Frog Game Frog
Third Frog Game Frog
etc
  

Спасибо за вашу помощь!

Комментарии:

1. Почему вы перебираете ключи словаря?

2. Ключи словаря соответствуют (примерно) типам организмов (например, ключом может быть «Reptile», а типом может быть «Reptiles»). Я хочу попытаться назначить классы (которые хранятся в значениях) соответствующим образом на основе перекрытия между типами и ключами.

3. хорошо, я также не понимаю, что вы делаете с i и tempnames — похоже, вы получаете доступ только к записи, соответствующей текущему организму, так зачем использовать список?

4. Это одна из моих многочисленных попыток решить проблему, о которой я упоминал выше (т. Е. Каждая амфибия заканчивается с тем же именем).). Похоже, что при последнем запуске функции каждому объекту с тем же типом присваивается одинаковое .name . Циклы For должны выполнять итерацию по каждому элементу только один раз, но что-то в этом коде, похоже, достигает нескольких экземпляров класса за одну развертку.

5. смотрите мой ответ — вы когда-либо создаете только один объект каждого типа, поэтому всякий раз, когда вы его изменяете, все ссылки на него отражают это изменение.

Ответ №1:

Вы когда-либо создаете только один экземпляр каждого класса (что происходит при создании typedict ), поэтому все ссылки на этот экземпляр (который holderlist заполняется, в отличие от отдельных экземпляров), безусловно, будут иметь одно и то же имя.

Попробуйте не создавать экземпляры классов в typedict , а вместо этого создавать экземпляры, когда вам это нужно в for цикле:

 typedict = {
"Reptiles" : Reptile,
"Amphibians" : Amphibian
... 
}
...

     holderlist[i] = typedict[key]()
  

Комментарии:

1. Это сработало как шарм — большое спасибо! Я не могу поверить, что это было что-то настолько простое. O.O