说我有一个数组数组,其中包含子项(作为每个数组的第0个元素)和父项(作为每个数组的第1个元素),就像这样:
[[child, parent], [child, parent], [child, parent]]
这是一个真实的例子:
[[Mary, Dan], [Dan, Steven], [Steven, Craig], [Janice, Keith]]
玛丽是丹的孩子,丹是史蒂文的孩子,史蒂文是克雷格的孩子。 Janice和Keith与该家庭没有联系。每个孩子只有一个父母。而且,配对代表该家庭的所有可能配对。由于Janice和Keith都不属于该家庭的任何其他孩子/父母配对,因此我们知道他们没有联系。
鉴于输入的是玛丽,我该如何创建一个循环,使克雷格成为玛丽的最老祖先?
我在想一个while循环,该循环将输入作为Mary,然后与Dan一起开始循环,然后与Steven一起开始循环,然后与Craig一起开始循环,然后在没有找到匹配项的情况下返回Craig。但是,我希望它在理论上不受限制的祖先上工作。我觉得这应该很简单,但是除了在彼此之间写了一堆for循环而在100个祖先列表中不起作用的情况下,我没有找到一个可行的解决方案。
答案 0 :(得分:3)
您可以从数组中创建字典(从子级到父级),并使用while
循环方法:
data = [['Mary', 'Dan'], ['Dan', 'Steven'], ['Steven', 'Craig'], ['Janice', 'Keith']]
tree = {child: parent for child, parent in data}
def oldest_ancestor(child):
parent = child
while tree.get(parent, None) is not None:
parent = tree[parent]
return parent
print(oldest_ancestor('Mary')) # Craig
答案 1 :(得分:2)
您可以执行以下操作:
data = [['Mary', 'Dan'], ['Dan', 'Steven'], ['Steven', 'Craig'], ['Janice', 'Keith']]
def get_oldest_ancestor(d, source):
def getParent(d, source):
return next((parent for child, parent in d if child == source), None)
while True:
parent = getParent(d, source)
if parent:
source = parent
else:
return source
ancestor = get_oldest_ancestor(data, 'Mary')
print(ancestor)
输出
Craig
答案 2 :(得分:0)
您需要将孩子的父母与其他孩子的父母进行比较,以查看是否存在。
family = [["Mary", "Dan"], ["Dan", "Steven"], ["Steven", "Craig"],["Janice", "Keith"]]
def oldestAncestor(child):
directParent = ""
for pair in family:
if pair[0] == child:
directParent = pair[1]
pass
if directParent == pair[0]:
directParent = pair[1]
pass
pass
return directParent
print (oldestAncestor("Mary"))
answer
Craig
答案 3 :(得分:0)
另一种方法是使用networkx
中的bfs_predecessors
算法:
In[43]:
import pandas as pd
import networkx as nx
edges=[['Mary', 'Dan'], ['Dan', 'Steven'], ['Steven', 'Craig'], ['Janice', 'Keith']]
G = nx.DiGraph()
G.add_edges_from(edges)
df = pd.DataFrame(edges, columns=['child','parent'])
df['oldest_descendant'] = df['child'].apply(lambda x: list(nx.bfs_predecessors(G,x))[-1][0])
df
Out[43]:
child parent oldest_descendant
0 Mary Dan Craig
1 Dan Steven Craig
2 Steven Craig Craig
3 Janice Keith Keith
我使用pandas数据框只是为了说明问题,但在这里,我从配对中制作了一个有向图,以便可以使用该算法。我使用这些边缘填充df,然后添加“ oldest_desendant”列,这仅在每个子代上调用算法,然后将生成器对象转换为返回元组列表的列表:
In[41]:
list(nx.bfs_predecessors(G,'Mary'))
Out[41]: [('Dan', 'Mary'), ('Steven', 'Dan'), ('Craig', 'Steven')]
所以我只使用[-1][0]