Python получить окончательный класс вложенных классов - PullRequest
0 голосов
/ 19 мая 2019

Я создаю функцию семейного древа для своего веб-приложения, создающего мир, и использую данные, взятые из списка, пример, который я использую:

            # PERSON                # SPOUSE             # MOTHER          # FATHER             # SEX       # HOUSE
listChars = [['Ned Stark',          'Catelyn Tully',    'Lyarra Stark',     'Rickard Stark',    'Male',     'Stark'],
             ['Catelyn Tully',      'Ned Stark',        'Minisa Whent',     'Hoster Tully',     'Female',   'Stark'],
             ['Robb Stark',         'Talisa Maegyr',    'Catelyn Tully',    'Ned Stark',        'Male',     'Stark'],
             ['Bran Stark',         'None',             'Catelyn Tully',    'Ned Stark',        'Male',     'Stark'],
             ['Sansa Stark',        'Tyrion Lannister', 'Catelyn Tully',    'Ned Stark',        'Female',   'Stark'],
             ['Tywin Lannister',    'Joanna Lannister', 'Jeyne Marbrand',   'Tytos Lannister',  'Male',     'Lannister'],
             ['Jaime Lannister',    'Cersei Lannister', 'Joanna Lannister', 'Tywin Lannister',  'Male',     'Lannister'],
             ['Cersei Lannister',   'Jaime Lannister',  'Joanna Lannister', 'Tywin Lannister',  'Female',   'Lannister'],
             ['Tyrion Lannister',   'Sansa Stark',      'Joanna Lannister', 'Tywin Lannister',  'Male',     'Lannister'],
             ['Joffrey Baratheon',  'None',             'Cersei Lannister', 'Jaime Lannister',  'Male',     'Lannister'],
             ['Myrcella Baratheon', 'None',             'Cersei Lannister', 'Jaime Lannister',  'Female',   'Lannister'],
             ['Tommen Baratheon',   'None',             'Cersei Lannister', 'Jaime Lannister',  'Male',     'Lannister'],
             ['Rickon Stark',       'None',             'Talisa Maegyr',    'Robb Stark',       'Male',     'Stark'],
             ['Lyanna Lannister',   'None',             'Sansa Stark',      'Tyrion Lannister', 'Male',     'Lannister']]

Пока что я создал два класса: Household и Family. Класс Household содержит название дома, старших родителей дома, в которых больше нет предков / родителей, и старших родителей. У него также есть список families, который содержит семейства детей старших родителей (список Family экземпляров классов). В классе Family есть список родителей, дома, детей и семей (для детей детей родителей высшего уровня). Вот мой код для двух классов:

class Family:
    def __init__(self,parents,house):
        self.parents=parents
        self.house = house
        self.children=self.getChildren()
        self.families=self.createFamilies()

    def getChildren(self):
        childs = [row[0] for row in listChars if (row[2]==self.parents[1] and row[3]==self.parents[0]) or (row[2]==self.parents[0] and row[3]==self.parents[1])]
        return childs

    def createFamilies(self):
        family_list = []                
        for child in self.children:
            childRow = [row for row in listChars if row[0]==child][0]
            # if child has no spouse, no family
            if childRow[1] != 'None':
                if family_list !=[]:
                    for f in family_list:
                        if childRow[0] not in family_list and childRow[0] not in f.parents: # deals with a Jaime/Cersei scenario
                            family_list.append(Family((childRow[0],childRow[1]),self.house))
                else:
                    family_list.append(Family((childRow[0],childRow[1]),self.house))
        return family_list

    def __repr__(self):
        return '<Family parents:%s, children:%s>' % (self.parents,self.children)

class Household:
    def __init__(self,house,parents):
        self.house=house
        self.parents=parents
        self.children = self.getChildren()
        self.families=self.createFamilies()

    def getChildren(self):
        childs = [row[0] for row in listChars if row[2]==self.parents[0] or row[3]==self.parents[1]]
        return childs

    def createFamilies(self):
        fams = []
        for child in self.children:
            childRow = [row for row in listChars if row[0]==child][0]
            if childRow[1] != 'None':
                fams.append(Family((childRow[0],childRow[1]),self.house))
        return fams

    def __repr__(self):
        return '<Household house:%s, top-parents:%s, children:%s>' % (self.house,self.parents,self.children)

Затем я создаю экземпляры Household и помещаю их в household_list:

parents = list(set([(r[2],r[3]) for r in listChars])) # list of parents, no duplicates
parentsTop = {}.fromkeys(parents)

names = [r[0] for r in listChars]

# TRUE if parents TOP of household, FALSE if not
parentsTop = {p:([True] if p[0] not in names and p[1] not in names else [False]) for p in parentsTop}

# for now, get House as fathers last name
for p in parentsTop:
    if parentsTop[p]==[True]:
        parentsTop[p].append(p[1].split(' ')[-1])

household_list=[Household(parentsTop[ps][1],ps) for ps in parentsTop if parentsTop[ps][0]==True]

Цель этого - отформатировать таким образом, чтобы его можно было прочитать в файл .yml, а затем с помощью kingraph создать svg данных.

В настоящее время мне интересно, как я мог получить доступ ко всем семьям в семьях. Так, например, сейчас я знаю, что, скажем, для домохозяйства «Ланнистер» это будет выглядеть так (только для последнего мужчины): «Тиос» -> «Тайвин» -> «Хайме» -> Джоффри, так что есть два уровня семейных экземпляров. Как бы я смог пройти через все экземпляры Family, учитывая, что я не знаю, сколько существует уровней? Я ценю любые советы и любые пункты в правильном направлении. Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...