如何在这个(简单的)python过程中正确使用递归?
伙计们,我写了一个函数来测试两个输入a和b是否具有相同的数据结构,方法如下:如何在这个(简单的)python过程中正确使用递归?,python,data-structures,recursion,Python,Data Structures,Recursion,伙计们,我写了一个函数来测试两个输入a和b是否具有相同的数据结构,方法如下: print same_structure([1, 0, 1], [a, b, c]) #>>> True #print same_structure([1, [0], 1], [2, 5, 3]) >>> False #print same_structure([1, [2, [3, [4, 5]]]], ['a', ['b', ['c', ['d', 'e']]]]) >&g
print same_structure([1, 0, 1], [a, b, c])
#>>> True
#print same_structure([1, [0], 1], [2, 5, 3])
>>> False
#print same_structure([1, [2, [3, [4, 5]]]], ['a', ['b', ['c', ['d', 'e']]]])
>>> True
#print same_structure([1, [2, [3, [4, 5]]]], ['a', ['b', ['c', ['de']]]])
>>> False
这个函数在我的实现中使用递归。我是递归的初学者,递归思维仍然有困难。此外,为了避免欺骗答案,我想使用我自己的凌乱代码,并通过它学习使用以下代码行的递归调用:“相同的_结构返回a[I],b[e]”。有人能在下面的代码中演示如何正确使用递归吗?
提前感谢您的帮助
def is_list(p):
return isinstance(p, list)
def same_structure(a,b):
if not is_list(a) and not is_list(b):
print '#1'
return True
else:
if is_list(a) and is_list(b):
print '#2'
if len(a) != len(b):
print '#3'
return False
if len(a) == len(b):
print '#4'
for e in range(len(a)):
print 'e = ', e, 'a[e]= ', a[e], 'b[e]=', b[e]
return same_structure(a[e], b[e])
else:
return False
以下工作:
def same_structure(a, b):
if isinstance(a, list) and isinstance(b, list) and len(a) == len(b):
return all(same_structure(A, B) for A, B in zip(a, b))
return (not isinstance(a, list) and not isinstance(b, list))
编写递归函数时,首先需要考虑基本情况,即只返回一个值,而不调用任何递归。这里的基本情况是以下条件之一:
a是列表,b不是,反之亦然:返回False
a和b都是列表,但长度不同:返回False
a或b都不是列表:返回True
如果a和b都是列表,并且它们具有相同的长度,那么我们现在需要递归地检查这些列表的每个元素。zipa,b提供了一种方便的方法,可以一起迭代每个列表中的元素,如果任意两个子元素的相同_结构的结果为False,我们希望整个函数返回False。这就是使用all的原因,如果您不熟悉all,则它与以下循环等效,但效率更高:
match = True
for A, B in zip(a, b):
if not same_structure(A, B):
match = False
break
return match
下面是如何在不做太多更改的情况下重写函数,其逻辑实际上与我的解决方案非常相似,但就在您过早从该循环返回的打印“4”下方:
def same_structure(a,b):
if not is_list(a) and not is_list(b):
print '#1'
return True
else:
if is_list(a) and is_list(b):
print '#2'
if len(a) != len(b):
print '#3'
return False
if len(a) == len(b):
print '#4'
for e in range(len(a)):
print 'e = ', e, 'a[e]= ', a[e], 'b[e]=', b[e]
if not same_structure(a[e], b[e]):
return False
return True
else:
return False
以下工作:
def same_structure(a, b):
if isinstance(a, list) and isinstance(b, list) and len(a) == len(b):
return all(same_structure(A, B) for A, B in zip(a, b))
return (not isinstance(a, list) and not isinstance(b, list))
编写递归函数时,首先需要考虑基本情况,即只返回一个值,而不调用任何递归。这里的基本情况是以下条件之一:
a是列表,b不是,反之亦然:返回False
a和b都是列表,但长度不同:返回False
a或b都不是列表:返回True
如果a和b都是列表,并且它们具有相同的长度,那么我们现在需要递归地检查这些列表的每个元素。zipa,b提供了一种方便的方法,可以一起迭代每个列表中的元素,如果任意两个子元素的相同_结构的结果为False,我们希望整个函数返回False。这就是使用all的原因,如果您不熟悉all,则它与以下循环等效,但效率更高:
match = True
for A, B in zip(a, b):
if not same_structure(A, B):
match = False
break
return match
下面是如何在不做太多更改的情况下重写函数,其逻辑实际上与我的解决方案非常相似,但就在您过早从该循环返回的打印“4”下方:
def same_structure(a,b):
if not is_list(a) and not is_list(b):
print '#1'
return True
else:
if is_list(a) and is_list(b):
print '#2'
if len(a) != len(b):
print '#3'
return False
if len(a) == len(b):
print '#4'
for e in range(len(a)):
print 'e = ', e, 'a[e]= ', a[e], 'b[e]=', b[e]
if not same_structure(a[e], b[e]):
return False
return True
else:
return False
您只执行第一个递归调用,因为您将立即返回
如果我理解您想要做什么,您需要调用与子元素相同的_结构,并检查它的返回值,而不是立即返回它。如果任何调用的结果为false,则返回false,否则返回true。您只执行第一个递归调用,因为您将立即返回
如果我理解您想要做什么,您需要调用与子元素相同的_结构,并检查它的返回值,而不是立即返回它。如果任何调用的结果为false,则返回false,否则返回true。尝试此解决方案,它适用于所有示例,并且以递归函数式编程风格编写,但不使用zip、all等。在每个步骤中,仅使用片段来减少列表的大小:
def same_structure(a, b):
if a == [] or b == []:
return a == b
elif is_list(a[0]) != is_list(b[0]):
return False
elif not is_list(a[0]):
return same_structure(a[1:], b[1:])
else:
return same_structure(a[0], b[0]) and same_structure(a[1:], b[1:])
尝试此解决方案,它适用于您的所有示例,并以递归、函数式编程风格编写,但不使用zip、all等。在每个步骤中,仅使用片段来减少列表的大小:
def same_structure(a, b):
if a == [] or b == []:
return a == b
elif is_list(a[0]) != is_list(b[0]):
return False
elif not is_list(a[0]):
return same_structure(a[1:], b[1:])
else:
return same_structure(a[0], b[0]) and same_structure(a[1:], b[1:])
嗨,@F.J!你的代码比我的好得多谢谢!。但我不想在这个硬件中使用zip或all。此外,为了避免欺骗答案,我想用我自己的凌乱代码,通过它,学习如何使用递归调用修复代码行“相同的_结构返回a[I],b[e]”。@Pythonista'sApprentice我在大约10分钟前做了一次编辑,其中有一个编辑版本的函数应该可以工作,但仍然遵循这些要求。嗨,@F.J!你的代码比我的好得多谢谢!。但我不想在这个硬件中使用zip或all。此外,为了避免欺骗答案,我想用我自己的凌乱代码,通过它,学习如何使用递归调用修复代码行“相同的_结构返回a[I],b[e]”。@Pythonista'sApprentice我在大约10分钟前做了一次编辑,其中有一个编辑版本的函数应该可以工作,同时仍然遵循这些要求。