Python中带for循环的递归函数

2024-04-20 03:34:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试在Python中做一个递归函数来获取所有从给定子对象开始的父对象-例如,如果我想找到所有从a开始的父对象-a有父对象B和C,B有父对象D和E,C有父对象F和G,所以函数应该返回set:{B,C,D,E,F,G} 我有一个班绅士,我把所有的人都救了进去自我。人(实例,而不是名称)和一个类Person,它的方法get_parents()可以返回False或父元素的元组(类Person的2个实例)

以下是包含类和方法的整个文件:

class Person:
    def __init__(self, name, gender, education, father = False, mother = False):
        self.name = name
        self.gender = gender
        self.education = education
        self.father = father
        self.mother = mother
        self.children = []
    def add_parent(self, inst):
        if inst.gender=="m":
            self.father = inst
        else:
            self.mother = inst
    def add_child(self, inst):
        self.children.append(inst)
    def has_parent(self):
        return True if self.father or self.mother else False
    def get_parents(self):
        if self.has_parent():
            if self.father and self.mother: return self.father, self.mother
            if self.father and not self.mother: return self.father
            if self.mother and not self.father: return self.mother
        else:
            return ()

class GenTree:
    def __init__(self):
        self.people = {}
    def load_from_file(self, file_name):
        data = open(file_name, "r")
        people = {}
        reading = "person"
        for line in data:
            line = line.rstrip()
            reading = "fam" if line=="" else reading
            if reading=="person":
                thisInfo = line.split(";")
                thisName = thisInfo[0]
                thisGender = thisInfo[1]
                thisEd = thisInfo[2]
                self.people[thisName] = Person(thisName, thisGender, thisEd)
            else:
                if line == "":
                    continue
                thisInfo = line.split("=>")
                for i in range(len(thisInfo)):
                    thisInfo[i] = thisInfo[i].rstrip()
                    thisInfo[i] = thisInfo[i].strip(" ")
                self.people[thisInfo[1]].add_parent(self.people[thisInfo[0]])
                self.people[thisInfo[0]].add_child(self.people[thisInfo[1]])

    def get_all_parents(self, child_name):
        child = self.people[child_name]
        parents = child.get_parents()
        if parents:
            for parent in parents:
                return parents + self.get_all_parents(parent.name)
        return parents

g = GenTree()
g.load_from_file("data_a")
print([i.name for i in g.get_all_parents('Katka')])

下面是包含给定数据的文件:

^{pr2}$

现在,“print([i.name for i in g.get_all_parents('Katka'))”应该返回:

{'Jirka', 'Dana', 'Zdenek', 'Anna', 'Stefan', 'Ales', 'Tereza', 'David', 'Sasa', 'Tomas', 'Juraj', 'Vaclav', 'Michaela'}

但它回来了

['Jirka', 'Dana', 'Zdenek', 'Anna', 'Ales', 'Tereza']

但它总是这样的”你自己去找你所有的父母(父级名称)“只针对for循环中的第一个 另外,我不知道如何将它作为一个集合返回(我尝试了get_all_parents(self,child_name,allparents=set()),但它似乎没有在每次调用函数时重置allparents集)


Tags: 对象nameselfchildgetreturnifdef
1条回答
网友
1楼 · 发布于 2024-04-20 03:34:53

在大多数情况下,使用for循环和递归不是一个好主意。事实上他们是一样的。Haskell(函数式编程语言)没有for循环

def get_all_parents(self, child_name):
        child = self.people[child_name]
        parents = child.get_parents()
        if parents:
            return parents + self.get_all_parents(parent[0].name) + self.get_all_parents(parent[1].name)

        return parents

简单的递归调用意味着调用自己一次或多次

^{pr2}$

这里get_all_parents将返回它的值,正好在它的位置+。。。。在

编辑

在特殊情况下,你可以使用for循环,但是这种编码方式非常混乱,很难解释

def get_all_parents(self, child_name , ret = ()):
    child = self.people[child_name]
    parents = child.get_parents()
    if parents:
        for p in parents:
            ret = self.get_all_parents(p.name , ret)
    return parents + ret

在这种情况下,我们需要一个额外的对象在每次调用之间移动并将结果添加到它。它类似于所有函数调用之间的共享对象。 你可以轻松地翻一个列表来设置这个问题已经回答了看How to construct a set out of list items in python?

相关问题 更多 >