想要一些帮助使函数尾递归
Wanted some help making a function tail recursive
我在 python 中创建了一个函数来展平字典对象。此类对象的示例如下:
x = {'items': [{'name': 'Contract',
'subItems': [{'name': 'Consultant'}, {'name': 'Direct'}]},
{'name': 'Permanent',
'subItems': [{'name': 'Full Time'}, {'name': 'Part Time'}]}]}
我现在使用的函数使用了一个单独的列表。这是函数:
final_list = []
def traverseGraph(g_list, level=[]):
for g_ in g_list:
if 'subItems' in g_:
traverseGraph(g_['subItems'], level+[g_['name']])
else:
final_list.append(level+[g_['name']])
给出以下正确输出:
traverseGraph(x['items'])
final_list
[['Contract', 'Consultant'],
['Contract', 'Direct'],
['Permanent', 'Full Time'],
['Permanent', 'Part Time']]
我想将此函数转换为不使用单独列表的尾递归函数。这是我有的,但不起作用。
def traverseGraph(g_list, level=[]):
for g_ in g_list:
if 'subItems' not in g_:
return (level + [g_['name']])
return traverseGraph(g_['subItems'], level + [g_['name']])
这是输出:
a = traverseGraph(x['items'])
print(a)
['Contract', 'Consultant']
我可以使用该列表,但我不想使用。在这一点上,它只是为了学习。谢谢!
这似乎可以很好地用作递归生成器:
def traverseGraph(g_list, level=[]):
for g_ in g_list:
if 'subItems' in g_:
yield from traverseGraph(g_['subItems'], level+[g_['name']])
else:
yield level+[g_['name']]
如果您真的想坚持使用列表但想要 return 您的结果,您要么需要将结果列表传递到调用链中,要么需要合并递归结果进入每个级别的列表。下面是将结果列表传递到调用链中的样子:
def traverseGraph(g_list, level=[], final_list=None):
if final_list is None:
final_list = []
for g_ in g_list:
if 'subItems' in g_:
traverseGraph(g_['subItems'], level+[g_['name']], final_list)
else:
final_list.append(level+[g_['name']])
return final_list
这是合并的样子:
def traverseGraph(g_list, level=[]):
final_list = []
for g_ in g_list:
if 'subItems' in g_:
final_list.extend(traverseGraph(g_['subItems'], level+[g_['name']]))
else:
final_list.append(level+[g_['name']])
return final_List
合并版本需要更多的数据复制,因此效率会降低。
None 这些实现是尾递归的。您可能需要多次递归,所以这不是一个真正的选择。
我在 python 中创建了一个函数来展平字典对象。此类对象的示例如下:
x = {'items': [{'name': 'Contract',
'subItems': [{'name': 'Consultant'}, {'name': 'Direct'}]},
{'name': 'Permanent',
'subItems': [{'name': 'Full Time'}, {'name': 'Part Time'}]}]}
我现在使用的函数使用了一个单独的列表。这是函数:
final_list = []
def traverseGraph(g_list, level=[]):
for g_ in g_list:
if 'subItems' in g_:
traverseGraph(g_['subItems'], level+[g_['name']])
else:
final_list.append(level+[g_['name']])
给出以下正确输出:
traverseGraph(x['items'])
final_list
[['Contract', 'Consultant'],
['Contract', 'Direct'],
['Permanent', 'Full Time'],
['Permanent', 'Part Time']]
我想将此函数转换为不使用单独列表的尾递归函数。这是我有的,但不起作用。
def traverseGraph(g_list, level=[]):
for g_ in g_list:
if 'subItems' not in g_:
return (level + [g_['name']])
return traverseGraph(g_['subItems'], level + [g_['name']])
这是输出:
a = traverseGraph(x['items'])
print(a)
['Contract', 'Consultant']
我可以使用该列表,但我不想使用。在这一点上,它只是为了学习。谢谢!
这似乎可以很好地用作递归生成器:
def traverseGraph(g_list, level=[]):
for g_ in g_list:
if 'subItems' in g_:
yield from traverseGraph(g_['subItems'], level+[g_['name']])
else:
yield level+[g_['name']]
如果您真的想坚持使用列表但想要 return 您的结果,您要么需要将结果列表传递到调用链中,要么需要合并递归结果进入每个级别的列表。下面是将结果列表传递到调用链中的样子:
def traverseGraph(g_list, level=[], final_list=None):
if final_list is None:
final_list = []
for g_ in g_list:
if 'subItems' in g_:
traverseGraph(g_['subItems'], level+[g_['name']], final_list)
else:
final_list.append(level+[g_['name']])
return final_list
这是合并的样子:
def traverseGraph(g_list, level=[]):
final_list = []
for g_ in g_list:
if 'subItems' in g_:
final_list.extend(traverseGraph(g_['subItems'], level+[g_['name']]))
else:
final_list.append(level+[g_['name']])
return final_List
合并版本需要更多的数据复制,因此效率会降低。
None 这些实现是尾递归的。您可能需要多次递归,所以这不是一个真正的选择。