Python 遍历数组以查找最高配对
假设我有一个数组,其中包含子元素(作为每个数组的第0个元素)及其父元素(作为每个数组的第1个元素),如下所示:Python 遍历数组以查找最高配对,python,python-2.7,loops,Python,Python 2.7,Loops,假设我有一个数组,其中包含子元素(作为每个数组的第0个元素)及其父元素(作为每个数组的第1个元素),如下所示: [[child, parent], [child, parent], [child, parent]] 下面是一个真实的例子: [[Mary, Dan], [Dan, Steven], [Steven, Craig], [Janice, Keith]] 玛丽是丹的孩子,丹是史蒂文的孩子,史蒂文是克雷格的孩子。Janice和Keith与这家人没有关系。每个孩子只有一个父母。此外,这些
[[child, parent], [child, parent], [child, parent]]
下面是一个真实的例子:
[[Mary, Dan], [Dan, Steven], [Steven, Craig], [Janice, Keith]]
玛丽是丹的孩子,丹是史蒂文的孩子,史蒂文是克雷格的孩子。Janice和Keith与这家人没有关系。每个孩子只有一个父母。此外,这些配对表示族的所有可能配对。由于Janice和Keith都不在该家庭的任何其他子女/父母配对中,我们知道他们之间没有联系
考虑到Mary是输入,我如何创建一个循环,将Craig作为Mary的最古老祖先返回
我在想一个while循环,以Mary为输入,然后与Dan开始循环,然后与Steven开始循环,然后与Craig开始循环,然后在没有找到匹配项时返回Craig。然而,我希望它能在理论上无限长的祖先身上工作。我觉得这应该很简单,但我还没有找到一个有效的解决方案,除了在彼此之间编写一组for循环,而这些循环在100个祖先的列表上是不起作用的。您可以这样做:
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
你可以这样做:
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
您可以从数组中创建字典(从子到父),并使用
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
您可以从数组中创建字典(从子到父),并使用
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
您需要将孩子的家长与其他每个孩子进行比较,以查看是否存在该家长
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"))
答复
Craig
您需要将孩子的家长与其他每个孩子进行比较,以查看是否存在该家长
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"))
答复
Craig
另一种方法是使用networkx
中的算法:
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”列,这只是调用每个子级的算法,我将generator对象转换为一个列表,该列表返回元组列表:
In[41]:
list(nx.bfs_predecessors(G,'Mary'))
Out[41]: [('Dan', 'Mary'), ('Steven', 'Dan'), ('Craig', 'Steven')]
因此,我只是使用[-1][0]
索引最后一个元组的第一个元素,另一种方法是使用networkx
中的算法:
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”列,这只是调用每个子级的算法,我将generator对象转换为一个列表,该列表返回元组列表:
In[41]:
list(nx.bfs_predecessors(G,'Mary'))
Out[41]: [('Dan', 'Mary'), ('Steven', 'Dan'), ('Craig', 'Steven')]
因此,我只是使用
[-1][0]
为最后一个元组的第一个元素建立索引。很抱歉,我需要添加一条规则:成对表示该族所有可能的成对。由于Janice和Keith都不在该家庭的任何其他子女/父母配对中,我们知道他们没有连接。一个孩子可以有一个以上的父母吗?不,每个孩子只有一个父母对不起,我需要添加一条规则:配对代表该家庭所有可能的配对。由于Janice和Keith都不在该家庭的任何其他子女/父母配对中,我们知道他们没有联系。一个孩子可以有一个以上的父母吗?不,每个孩子只有一个父母这不起作用,即数据=[['Mary'、'Janice']、['Mary'、'Dan']、['Dan'、['Steven'、['Steven'、'Craig']、['Janice'、'Keith']]示例中每个孩子有一个以上的家长,如注释中所述,这不可能发生。这不起作用,即数据=['Mary','Janice'],['Mary','Dan'],['Dan','Steven'],['Steven','Craig'],['Janice','Keith']。示例中每个孩子有一个以上的家长,如注释中所述,此情况无法发生我如何解释数组中的空值?例如:['Mary','Dan'],['Dan','Steven'],['Steven','Craig'],['Mary',None]@AshleyO我想你可以在构建字典时过滤掉这些名字:tree={child:parent For child,parent in data if parent}
@AshleyO尽管函数本身应该可以在None
父级上正常工作。我如何解释数组中的空值?例如:['Mary','Dan'],['Dan','Steven'],['Steven','Craig'],['Mary',None]@AshleyO我想你可以在构建字典时过滤掉这些名字:tree={child:parent For child,parent in data if parent}
@AshleyO,尽管这个函数应该可以很好地与None
parents一起工作。