Python 为什么移动到双链表前面的递归函数不起作用?

Python 为什么移动到双链表前面的递归函数不起作用?,python,data-structures,recursion,Python,Data Structures,Recursion,我是一名新手,刚刚完成edX的入门课程MIT 6.00.1x;以下内容与该课程期末考试的一个问题有关(现已结束,因此我可以寻求帮助)。让 用于创建双链接列表。假设node是类DLLNode的一个实例,它出现在双链接列表中。然后node.getBefore()返回列表中node的直接前导,但如果node位于列表的前面,因此没有前导,则返回None 我已经写了一个递归函数 我希望返回双链接列表中的第一个节点,作为参数给定列表中的已知节点nodeInList 我的问题:firstInList到达了正确

我是一名新手,刚刚完成edX的入门课程MIT 6.00.1x;以下内容与该课程期末考试的一个问题有关(现已结束,因此我可以寻求帮助)。让

用于创建双链接列表。假设
node
是类
DLLNode
的一个实例,它出现在双链接列表中。然后
node.getBefore()
返回列表中
node
的直接前导,但如果
node
位于列表的前面,因此没有前导,则返回
None

我已经写了一个递归函数

我希望返回双链接列表中的第一个节点,作为参数给定列表中的已知节点
nodeInList

我的问题:
firstInList
到达了正确的第一个节点,这可以通过打印第一个节点的货物来证明,而不考虑使用的具体
节点列表。但是只要
nodeInList
不是链表中的第一个节点,
firstInList(node)
的返回值就变成了
None
,而不是所需的第一个节点。此结论基于以下内容:例如,如果列表的第一个节点
node1
包含cargo
1
,然后是
node2
包含cargo
2
,则
firstInList(node2)=None
计算结果为
True
,但
firstInList(node2)==node1
计算结果为
False
。调用firstInList(node2).getCargo()
将返回一条错误消息

属性错误:“非类型”对象没有属性“getCargo”

另一个数据是
firstInList(node1)=node1
的计算结果为
True
;至少,这是我所期望的

这表明找到的
firstnode
没有像我想象的那样返回递归调用链。有人能解释为什么吗


(请不要建议我使用迭代而不是递归。我知道如何做到这一点。我正在尝试理解Python 2.7编写的代码的行为。)

好吧,看来您没有返回递归的结果,因此,函数在所有情况下都将返回默认的未初始化值,但退化函数只返回默认的未初始化值

最后一行应该是:

return firstInList(nodeInList.getBefore())

非常感谢Nathan Tuggy。起初我误解了你说的话,但事实上你是对的

一旦我更改了最后一行,我的
firstInList
函数就工作得很好

firstInList(nodeInList.getBefore())

阅读

返回firstInList(nodeInList.getBefore())


考虑到我花了这么多时间担心这件事,我认为这是一种我以后不大可能犯的错误。或者,如果我这样做了,我就能自己发现问题。

我考虑过你的答案可能重复,但它并不能真正回答问题。到达列表的
firstnode
是递归的基本情况,函数确实到达了该基本情况,打印出正确的
firstnode.cargo
值就证明了这一点。那么为什么一个简单的
returnfirstnode
指令不够用呢?@GregGrunberg因为
return
只从当前函数调用(堆栈帧)返回。如果不使用返回值,则将丢弃该值。但是调用它的函数必须返回一些东西。如果您没有明确地说什么,它只会根据语言(平台)返回一些值。在python中,它返回
None
,在C\C++中,它返回一些垃圾,或者它不会在具有更严格规则的语言中编译。您也可以阅读以下文章-。请在代码中添加更改,以供将来参考,因为您的答案是正确的,但没有说明如何解决此问题it@holroy字体我明白了,我忘了告诉你是我干的!
def firstInList(nodeInList):
    """ Prints out the cargo carried by the first node in that doubly linked list
    of which nodeInList is a part.  Returns that first node. """

    if nodeInList.getBefore() == None:
        firstnode = nodeInList
        print firstnode.getCargo()
        return firstnode
    # nodeInList.getBefore() is not None, so nodeInList has an immediate predecessor 
    # on which firstInList can be be called.
    firstInList(nodeInList.getBefore())
return firstInList(nodeInList.getBefore())