我正在开发一个使用递归来反转链表的Python程序.我已经实现了反转函数,并添加了打印语句来帮助我理解该过程.但是,当我包含某些打印语句时,程序挂起并且无法完成.这种逆转似乎在没有这些印刷声明的情况下运作良好.

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

    def __repr__(self):
        next = self.next
        val = self.val
        out = f"ListNode({val}, "
        count_paren = 1
        while next is not None:
            val = next.val
            out += f"ListNode({val}, "
            next = next.next
            count_paren += 1
        out += f"{next}"
        out += count_paren * ")"
        return out

def reverse(head):
    if not head or not head.next:
        return head
    print("1 HEAD", head)
    new_head = reverse(head.next)
    print("2 NEW_HEAD", new_head)
    head.next.next = head
    print("3 HEAD", head)
    print("4 NEW_HEAD", new_head)
    head.next = None
    print("5 HEAD", head)
    print("6 NEW_HEAD", new_head)
    return new_head

lst = ListNode(1, ListNode(2, ListNode(3, ListNode(4, ListNode(5)))))
print(lst)
print(reverse(lst))

不使用PRINT语句:

    print("3 HEAD", head)
    print("4 NEW_HEAD", new_head)

这种反转效果很好.但是,如果我取消对这些行的注释,程序就会挂起.

对于为什么会发生这种情况,以及我如何修改打印语句以更好地理解该过程而不会导致挂起,我将不胜感激.我使用的是PYTHON版本的3.11.2.

推荐答案

问题是,您设置为head.next.next = head,然后用print("3 HEAD", head)print("4 NEW_HEAD", new_head)呼叫__repr__.在__repr__中,循环迭代地找到.next属性,但这会导致无限循环,因为在两次迭代之后,正在处理的 node 是head.next.next,而您已将其本身设置为head!循环中的值next为:

head->;head.next->;head.next.next(=head)->;head.next->;head.next.next(=head)

正如您所看到的,这会导致循环,因此删除print语句可以修复该问题.

实际上,您可以通过在函数的前面‘打断’.next的链条来完全防止形成循环.要做到这一点,一种方法是在函数开始时引用head.next,然后我们可以安全地设置head.next = None,而不会有导致无限循环的风险;如果运行此函数,您将看到我们可以在任何地方安全地调用__repr__:

def reverse(head):
    if not head or not head.next:
        return head
    print(f"1 {head = }")
    head_next = head.next
    print(f"2 {head = }")
    head.next = None
    print(f"3 {head = }")
    new_head = reverse(head_next)
    print(f"4 {head = }\n{new_head = }")
    head_next.next = head
    print(f"5 {head = }\n{new_head = }")
    return new_head

此外,您还可以通过使__repr__函数变得递归来简化它:

    def __repr__(self):
        return f"ListNode({self.val}, {self.next})"

Python相关问答推荐

通过优化空间在Python中的饼图中添加标签

acme错误-Veritas错误:模块收件箱没有属性linear_util'

TARete错误:类型对象任务没有属性模型'

Django mysql图标不适用于小 case

Mistral模型为不同的输入文本生成相同的嵌入

在Python argparse包中添加formatter_class MetavarTypeHelpFormatter时, - help不再工作""""

把一个pandas文件夹从juyter笔记本放到堆栈溢出问题中的最快方法?

isinstance()在使用dill.dump和dill.load后,对列表中包含的对象失败

在Python中调用变量(特别是Tkinter)

Maya Python脚本将纹理应用于所有对象,而不是选定对象

ConversationalRetrivalChain引发键错误

基于多个数组的多个条件将值添加到numpy数组

Discord.py -

使用__json__的 pyramid 在客户端返回意外格式

将链中的矩阵乘法应用于多组值

如果有2个或3个,则从pandas列中删除空格

Pandas 数据帧中的枚举,不能在枚举列上执行GROUP BY吗?

如何在验证文本列表时使正则表达式无序?

TypeError:';Locator';对象无法在PlayWriter中使用.first()调用

对包含JSON列的DataFrame进行分组