遍历数组以找到最高配对

时间:2018-12-17 15:58:29

标签: python python-2.7 loops

说我有一个数组数组,其中包含子项(作为每个数组的第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个祖先列表中不起作用的情况下,我没有找到一个可行的解决方案。

4 个答案:

答案 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]

为最后一个元组的第一个元素建立索引