【问题标题】:Why creating an instance of a class within a class method changes the 'self' argument?为什么在类方法中创建类的实例会改变“self”参数?
【发布时间】:2021-03-14 01:27:11
【问题描述】:

我正在用 Python 编写一个链表,但遇到了一个对调试来说非常麻烦和可怕的问题,我觉得我错过了一些关于 Python 的东西。我应该创建一个具有一些基本功能的单链表。其中一个是 take() 函数,它旨在创建一个包含原始列表的 n 个第一个元素的新列表。 但是,创建 LinkedList 类的新实例似乎会更改 .self 参数并且修改了变量节点,因为属性 .next 变为 None。结果,当创建一个列表,然后尝试从其中的 n 个元素中创建一个新列表时,程序会无限期地运行,但无论我看哪一部分,我都找不到循环或它背后的原因。

class LinkedList:
    def __init__(self, head=None):
        self.head = head


    def is_empty(self):
        if self.head == None:
            return True
        else:
            return False

    def add_last(self, node):
        if self.is_empty():
            self.head = node
            return
        nextEl = self.head
        while True:
            if nextEl.next is None:
                nextEl.next = node
                return
            nextEl = nextEl.next


    def take(self, n):
        node = self.head
        newHead = self.head
        newHead.next = None
        newList = LinkedList(newHead)
        count = 0
        while count < n:
            newList.add_last(node.next)
            node = node.next
            count += 1
        return newList

class Node:
    def __init__(self, data, next=None):
        self.data = data
        self.next = next

感谢您的所有帮助。

【问题讨论】:

  • newHead = self.head 不会创建新的头部。它将self.head 处的相同对象分配给变量newHead。因此,您的新链表 LinkedList(newHead) 是使用与旧链表共享的节点创建的

标签: python list linked-list


【解决方案1】:

take()函数中的一行

newHead.next = None

修改链表的一个节点,打破这个链表。您可以按如下方式解决此问题:

def take(self, n):
    node = self.head
    newHead = Node(self.head.data)
    newList = LinkedList(newHead)
    count = 0
    while count < n:
        newList.add_last(node.next)
        node = node.next
        count += 1
    return newList

然而,这仍然无法正常工作,因为add_last() 函数也存在问题。我认为这个函数应该添加一个节点作为链表的最后一个元素,但是由于您没有修改该节点的next 属性,因此您实际上附加了一个从该节点开始的整个链表。这可以通过以下方式解决:

def add_last(self, node):
    if self.is_empty():
        self.head = node
        return
    nextEl = self.head
    while True:
        if nextEl.next is None:
            nextEl.next = Node(node.data)     
            return
        nextEl = nextEl.next

还有更多问题。例如,take(sefl, n) 实际上会创建一个由n+1 元素组成的列表,如果将其应用于没有那么多元素的链表,则会引发异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-13
    • 2020-11-06
    • 2022-01-05
    • 2018-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多