使用 Python 中的递归函数在家谱中保存后代
Save descendence in family tree with a recursive function in Python
我有一个家谱字典,其中 child 的名字作为键,列表中他们爸爸妈妈的名字作为值。
d = {
'Kevin': ('Tom', 'Marge'),
'Marge': ('John', 'Mary'),
'Elle': ('Tom', 'Marge'),
'Seth': ('Tom', 'Marge'),
'Mary': ('Carl', 'Elena'),
'Tom': ('Joseph', 'Alice'),
'Alice': ('Rob', 'Amy'),
'John': ('James', 'Elena'),
'Joseph': ('Adam', 'Emma'),
'James': ('Nick', 'Maria') }
我需要编写一个递归函数,以便在两个人之间存在后代时 return 为 True。如果有后代,它必须打印出关系链,即:
>>> print("Is there a lineage?", lineage('Amy', 'Kevin', d))
Amy
Alice
Tom
Kevin
Is there a lineage? True
否则如果没有:
>>> print("Is there a lineage?", lineage('Mary', 'Alice', d))
Is there a lineage? False
这就是我目前所知道的。似乎 return True or False 始终如一,但我在弄清楚如何保存两个人之间的路径时遇到了麻烦。
line = []
def lineage(parent, child, d):
dad, mom = d[child][0], d[child][1]
try:
if parent in d[child]:
line.append(parent)
else:
try:
lineage(parent, dad, d)
except:
lineage(parent, mom, d)
return True
except:
return False
我是递归的新手,所以非常感谢任何关于如何处理这个问题的想法或帮助。
- 当路径存在时,我将你的函数 return 作为路径,而不是
True
。
- 我建议避免在此处
try / except
。
的确,尝试访问 d[child]
而不检查 child
是否在 d
中可能会导致异常。但是,这是递归的基本情况;如果基本情况在函数开头用明确的 if
明确标识,而不是在函数末尾没有解释的模糊“发生了一些异常”,那么您的代码将更容易理解。
def lineage(parent, child, d):
if parent == child:
return [child]
elif child not in d:
return False
else:
dad, mom = d[child][0], d[child][1]
path_via_dad = lineage(parent, dad, d)
if path_via_dad:
path_via_dad.append(child)
return path_via_dad
else:
path_via_mom = lineage(parent, mom, d)
if path_via_mom:
path_via_mom.append(child)
return path_via_mom
else:
return False
这是一个更短的等效版本,它依赖于 python 中逻辑运算符 or
的特定行为:
def lineage(parent, child, d):
if parent == child:
return [child]
elif child not in d:
return False
else:
dad, mom = d[child][0], d[child][1]
path = lineage(parent, dad, d) or lineage(parent, mom, d)
if path:
path.append(child)
return path
测试:
>>> lineage('Amy', 'Kevin', d)
['Amy', 'Alice', 'Tom', 'Kevin']
>>> lineage('Mary', 'Alice', d)
False
我有一个家谱字典,其中 child 的名字作为键,列表中他们爸爸妈妈的名字作为值。
d = {
'Kevin': ('Tom', 'Marge'),
'Marge': ('John', 'Mary'),
'Elle': ('Tom', 'Marge'),
'Seth': ('Tom', 'Marge'),
'Mary': ('Carl', 'Elena'),
'Tom': ('Joseph', 'Alice'),
'Alice': ('Rob', 'Amy'),
'John': ('James', 'Elena'),
'Joseph': ('Adam', 'Emma'),
'James': ('Nick', 'Maria') }
我需要编写一个递归函数,以便在两个人之间存在后代时 return 为 True。如果有后代,它必须打印出关系链,即:
>>> print("Is there a lineage?", lineage('Amy', 'Kevin', d))
Amy
Alice
Tom
Kevin
Is there a lineage? True
否则如果没有:
>>> print("Is there a lineage?", lineage('Mary', 'Alice', d))
Is there a lineage? False
这就是我目前所知道的。似乎 return True or False 始终如一,但我在弄清楚如何保存两个人之间的路径时遇到了麻烦。
line = []
def lineage(parent, child, d):
dad, mom = d[child][0], d[child][1]
try:
if parent in d[child]:
line.append(parent)
else:
try:
lineage(parent, dad, d)
except:
lineage(parent, mom, d)
return True
except:
return False
我是递归的新手,所以非常感谢任何关于如何处理这个问题的想法或帮助。
- 当路径存在时,我将你的函数 return 作为路径,而不是
True
。 - 我建议避免在此处
try / except
。
的确,尝试访问 d[child]
而不检查 child
是否在 d
中可能会导致异常。但是,这是递归的基本情况;如果基本情况在函数开头用明确的 if
明确标识,而不是在函数末尾没有解释的模糊“发生了一些异常”,那么您的代码将更容易理解。
def lineage(parent, child, d):
if parent == child:
return [child]
elif child not in d:
return False
else:
dad, mom = d[child][0], d[child][1]
path_via_dad = lineage(parent, dad, d)
if path_via_dad:
path_via_dad.append(child)
return path_via_dad
else:
path_via_mom = lineage(parent, mom, d)
if path_via_mom:
path_via_mom.append(child)
return path_via_mom
else:
return False
这是一个更短的等效版本,它依赖于 python 中逻辑运算符 or
的特定行为:
def lineage(parent, child, d):
if parent == child:
return [child]
elif child not in d:
return False
else:
dad, mom = d[child][0], d[child][1]
path = lineage(parent, dad, d) or lineage(parent, mom, d)
if path:
path.append(child)
return path
测试:
>>> lineage('Amy', 'Kevin', d)
['Amy', 'Alice', 'Tom', 'Kevin']
>>> lineage('Mary', 'Alice', d)
False