为什么我的函数只在第二个 return 语句中 returning object 而不是实际上触发 return 的第一个 return 语句
Why is my function only returning the object in the second return statement not the first return statement which is actually triggering the return
我有一些 xml 有一些未知深度的元素这里是一个示例元素
<someElement anAttribute="descriptiveandimportant">
<firstChild>
<childOfFirstChild anAttribute="someText">text_value</childOfFirstChild>
</firstChild>
<secondChild>
<daughterOfSecondChild>anotherText_value_1</daughterOfSecondChild>
<sonOfSecondChild>anotherText_value_2</sonOfSecondChild>
</secondChild>
</someElement>
我不知道 someElement 有多少 children 也不知道每个 child 有多少 children 。 . .它真的没有那么深入,但我正在处理一些野外数据,我不能假设我提前知道所有 children 和他们的 children。
我想要每个独特的 child 元素及其 children 。 . .
myOutput = [firstChild, childOfFirstChild, second_child, daughterOfSecondChild, sonOfSecondChild]
我写了一个函数 - 打印语句可以帮助我解决问题
def get_children(some_element_list):
new_elements_list = []
for e in some_element_list:
new_elements_list.append(e)
for child in e.iterchildren():
if child == e:
continue
if child in some_element_list:
continue
new_elements_list.append(child)
print (new_elements_list)
if new_elements_list == some_element_list:
print ('passed the test')
return some_element_list[1:] # when triggered
print('going to loop again')
some_element_list = get_children(new_elements_list) # returns here
return some_element_list # if this is not present nothing is returned
这是 运行 带有 someElement
的函数后的结果
>>> y = get_children([someElement])
[<Element someElement at 0x23f4cbbff40>, <Element firstChild at 0x23f4cc76f90>, <Element secondChild at 0x23f4cbbfc70>]
going to loop again
[<Element someElement at 0x23f4cbbff40>, <Element firstChild at 0x23f4cc76f90>, <Element childOfFirstChild at 0x23f4cc76a90>, <Element secondChild at 0x23f4cbbfc70>, <Element daughterOfSecondChild at 0x23f4cc769a0>, <Element sonOfSecondChild at 0x23f4cc76b30>]
going to loop again
[<Element someElement at 0x23f4cbbff40>, <Element firstChild at 0x23f4cc76f90>, <Element childOfFirstChild at 0x23f4cc76a90>, <Element secondChild at 0x23f4cbbfc70>, <Element daughterOfSecondChild at 0x23f4cc769a0>, <Element sonOfSecondChild at 0x23f4cc76b30>]
passed the test
我很挣扎,因为我最初有 final return 语句而没有为 return 命名任何东西 - 一旦我在第二个 return 语句函数 returns some_element_list[1:] - 换句话说,它 returns 是第一个 return 语句中定义的。
我从不编码 some_element_list = some_element_list[1:].
最后,当我试图思考如何提出这个问题时,我将最后的 return 语句更改为
return 'is this not interesting'
这就是 returned - 而不是 some_element_list[1:]
总而言之,我看到了两件对我来说没有意义的事情
- 我必须在函数的最终 return 语句中指定一些 object 到 return 任何东西 - 即使 return 在结束之前触发功能。
- some_element_list 实际上是 some_element_list[1:] 如果这是在第一个 return 语句
中定义的
基于下面的答案并且与问题有一定距离我现在理解了这个问题代码中的注释我希望能帮助解释下一个出现的人我的错误是认为当第一个 return 被触发 returned outside 到 caller 下面的解释帮助我到达那里
这是基本的递归,但令人困惑,因为它添加了 xml
与问题无关的位。
我能想到的最好的解释方式是:
if new_elements_list == some_element_list:
return some_element_list[1:]
是您的基本情况。
它在未指定的深度停止你的递归。
但是,您的结果仍然需要从嵌套调用中“冒出”。
由于此示例仅递归两次,因此很容易举例说明这是如何发生的。
假设some_element_list = get_children(new_elements_list)
不是递归的,它只是调用另一个函数。
这就是它查找您的案例的方式。
import lxml.etree
def get_children(some_element_list):
new_elements_list = []
for e in some_element_list:
new_elements_list.append(e)
for child in e.iterchildren():
if child == e:
continue
if child in some_element_list:
continue
new_elements_list.append(child)
# This can removed since it's actually only ever True in the
# recursive call
# if new_elements_list == some_element_list:
# return some_element_list[1:]
some_element_list = get_children_inner_call(new_elements_list)
return some_element_list
def get_children_inner_call(some_element_list):
new_elements_list = []
for e in some_element_list:
new_elements_list.append(e)
for child in e.iterchildren():
if child == e:
continue
if child in some_element_list:
continue
new_elements_list.append(child)
# Since it will be true in this "recursive" call
# it can be removed here
# if new_elements_list == some_element_list:
return some_element_list[1:]
foo = lxml.etree.fromstring(
'''<someElement anAttribute="descriptiveandimportant">
<firstChild>
<childOfFirstChild anAttribute="someText">text_value</childOfFirstChild>
</firstChild>
<secondChild>
<daughterOfSecondChild>anotherText_value_1</daughterOfSecondChild>
<sonOfSecondChild>anotherText_value_2</sonOfSecondChild>
</secondChild>
</someElement>
''')
print(get_children(foo))
如你所见,some_element_list
是从内部调用中得到的,实际上是some_element_list[1:]
。然后返回到您的外部函数调用。
如果您以前使用过递归,那么您以前见过这种模式。但是你的例子中有很多噪音可能导致了混乱。
我有一些 xml 有一些未知深度的元素这里是一个示例元素
<someElement anAttribute="descriptiveandimportant">
<firstChild>
<childOfFirstChild anAttribute="someText">text_value</childOfFirstChild>
</firstChild>
<secondChild>
<daughterOfSecondChild>anotherText_value_1</daughterOfSecondChild>
<sonOfSecondChild>anotherText_value_2</sonOfSecondChild>
</secondChild>
</someElement>
我不知道 someElement 有多少 children 也不知道每个 child 有多少 children 。 . .它真的没有那么深入,但我正在处理一些野外数据,我不能假设我提前知道所有 children 和他们的 children。
我想要每个独特的 child 元素及其 children 。 . .
myOutput = [firstChild, childOfFirstChild, second_child, daughterOfSecondChild, sonOfSecondChild]
我写了一个函数 - 打印语句可以帮助我解决问题
def get_children(some_element_list):
new_elements_list = []
for e in some_element_list:
new_elements_list.append(e)
for child in e.iterchildren():
if child == e:
continue
if child in some_element_list:
continue
new_elements_list.append(child)
print (new_elements_list)
if new_elements_list == some_element_list:
print ('passed the test')
return some_element_list[1:] # when triggered
print('going to loop again')
some_element_list = get_children(new_elements_list) # returns here
return some_element_list # if this is not present nothing is returned
这是 运行 带有 someElement
的函数后的结果>>> y = get_children([someElement])
[<Element someElement at 0x23f4cbbff40>, <Element firstChild at 0x23f4cc76f90>, <Element secondChild at 0x23f4cbbfc70>]
going to loop again
[<Element someElement at 0x23f4cbbff40>, <Element firstChild at 0x23f4cc76f90>, <Element childOfFirstChild at 0x23f4cc76a90>, <Element secondChild at 0x23f4cbbfc70>, <Element daughterOfSecondChild at 0x23f4cc769a0>, <Element sonOfSecondChild at 0x23f4cc76b30>]
going to loop again
[<Element someElement at 0x23f4cbbff40>, <Element firstChild at 0x23f4cc76f90>, <Element childOfFirstChild at 0x23f4cc76a90>, <Element secondChild at 0x23f4cbbfc70>, <Element daughterOfSecondChild at 0x23f4cc769a0>, <Element sonOfSecondChild at 0x23f4cc76b30>]
passed the test
我很挣扎,因为我最初有 final return 语句而没有为 return 命名任何东西 - 一旦我在第二个 return 语句函数 returns some_element_list[1:] - 换句话说,它 returns 是第一个 return 语句中定义的。
我从不编码 some_element_list = some_element_list[1:].
最后,当我试图思考如何提出这个问题时,我将最后的 return 语句更改为
return 'is this not interesting'
这就是 returned - 而不是 some_element_list[1:]
总而言之,我看到了两件对我来说没有意义的事情
- 我必须在函数的最终 return 语句中指定一些 object 到 return 任何东西 - 即使 return 在结束之前触发功能。
- some_element_list 实际上是 some_element_list[1:] 如果这是在第一个 return 语句 中定义的
基于下面的答案并且与问题有一定距离我现在理解了这个问题代码中的注释我希望能帮助解释下一个出现的人我的错误是认为当第一个 return 被触发 returned outside 到 caller 下面的解释帮助我到达那里
这是基本的递归,但令人困惑,因为它添加了 xml
与问题无关的位。
我能想到的最好的解释方式是:
if new_elements_list == some_element_list:
return some_element_list[1:]
是您的基本情况。
它在未指定的深度停止你的递归。 但是,您的结果仍然需要从嵌套调用中“冒出”。 由于此示例仅递归两次,因此很容易举例说明这是如何发生的。
假设some_element_list = get_children(new_elements_list)
不是递归的,它只是调用另一个函数。
这就是它查找您的案例的方式。
import lxml.etree
def get_children(some_element_list):
new_elements_list = []
for e in some_element_list:
new_elements_list.append(e)
for child in e.iterchildren():
if child == e:
continue
if child in some_element_list:
continue
new_elements_list.append(child)
# This can removed since it's actually only ever True in the
# recursive call
# if new_elements_list == some_element_list:
# return some_element_list[1:]
some_element_list = get_children_inner_call(new_elements_list)
return some_element_list
def get_children_inner_call(some_element_list):
new_elements_list = []
for e in some_element_list:
new_elements_list.append(e)
for child in e.iterchildren():
if child == e:
continue
if child in some_element_list:
continue
new_elements_list.append(child)
# Since it will be true in this "recursive" call
# it can be removed here
# if new_elements_list == some_element_list:
return some_element_list[1:]
foo = lxml.etree.fromstring(
'''<someElement anAttribute="descriptiveandimportant">
<firstChild>
<childOfFirstChild anAttribute="someText">text_value</childOfFirstChild>
</firstChild>
<secondChild>
<daughterOfSecondChild>anotherText_value_1</daughterOfSecondChild>
<sonOfSecondChild>anotherText_value_2</sonOfSecondChild>
</secondChild>
</someElement>
''')
print(get_children(foo))
如你所见,some_element_list
是从内部调用中得到的,实际上是some_element_list[1:]
。然后返回到您的外部函数调用。
如果您以前使用过递归,那么您以前见过这种模式。但是你的例子中有很多噪音可能导致了混乱。