【问题标题】:Behavior of del operator in PythonPython中del运算符的行为
【发布时间】:2013-12-09 15:09:07
【问题描述】:

我想知道为什么以下不起作用。

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

    def remove(self, value):
        if self is None:
            return False
        if self.data == value:
            if self.next:
                self.data = self.next.data
                self.next = self.next.next
            else:
                del self
        else:
            self.next.remove(value)

    node = Node(4)
    node.append(Node(3))
    node.remove(3)
    print node.next.data
    #prints 3

del 不会从链表中删除元素。我必须修改 delete() 函数,以便我有一个指向目标元素父级的指针。

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

    def remove(self, value):
        if self is None:
            return False
        if self.data == value:
            if self.next:
                self.data = self.next.data
                self.next = self.next.next
            else:
                del self
        else:
            current = self
            while current.next:
                if current.next.data == value:
                    if current.next.next:
                        current.next = current.next.next
                    else:
                        current.next = None

从控制台,

node = Node(4)
current = node
del current #node is not deleted because I am only deleting the pointer
del node #node is deleted

这对我来说似乎是合乎逻辑的。但是,我不确定为什么第一个代码块没有按预期工作。

【问题讨论】:

  • 查看此特定问题的最佳解决方案可能会有所帮助。
  • Python 中的变量只是事物的名称。 del 从对象中删除名称;这并不意味着“破坏对象”。我建议创建一个List 类来管理节点;如果您直接存储Nodes,您将无法在第一个节点中删除该东西,而没有尴尬的解决方法。
  • @user2357112 请将其作为答案发布 - 否则我们应该将其作为重复项关闭。

标签: python garbage-collection destroy reference-counting del


【解决方案1】:

我会解释为什么它不起作用。但首先您需要知道,您很少需要在 Python 中创建链表,因为列表类型已经为您提供了几乎所有功能。

>>> [2*i for i in range(10)]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
>>> list_1=[2*i for i in range(10)]
>>> i=0
>>> list_1[i]#first
0
>>> i=i+1
>>> list_1[i]#next
2
>>> list_1[-1]#last
18
>>> len(list_1)#size
10
>>> del list_1[-1]# del the last
#delete all (list_1 becomes empty)
for i in range(len(list_1)):
    del list_1[0]

在结束循环中,我们只删除前 n 次,但是当您删除列表中的第一个对象时,另一个对象会退回 1 个位置。这样您就可以轻松地操作列表,就像它们是链表一样,并删除任何元素而无需担心关于一个空槽。除此之外,list 还有一些非常有用的方法,例如 append、remove、sort、shuffle 等等。查看文档https://docs.python.org/3.5/library/stdtypes.html?highlight=list#list

现在回到你的问题: 让我们看看你的 remove 方法

if self is None:
    return False

这是没用的,你只能用具有这个方法的对象调用 .remove。 None.remove() 从不工作。如果 self 是 None 它会在任何(不可能的)调用之前抛出一个错误。

else:
    del self

当您在对象的方法中看到 self 时,它只是对对象本身的引用,del sel 只会删除本地引用。如果你真的想销毁一个对象,你必须在每个引用上用 del 销毁它。如果没有动态变量在查看它,Python 会忘记你的对象。您也可以覆盖引用。

>>> node = Node(4)
>>> node = 3# the Node object is erased because you can t have access to it

总的来说,除了创建链表之外,我并不真正了解您的 Node 类的目标,但正如我所说,您可以使用 list() 来做到这一点。一般来说,您不需要关心在 Python 中删除或不删除的内容,因为如果没有对对象的引用,Python 将覆盖内存。

【讨论】:

  • Node.remove(None, foo) 会起作用并导致self is None - 但这不是你需要考虑的。
  • 它会抛出 TypeError: remove() 接受 2 个位置参数,但给出了 3 个。因为方法使 self 成为 -->. 之前的样子
  • 错了。当直接在类上调用它时,你有一个未绑定的方法,它接受一个显式的self。但是,我忘记了 Python 确保您只传递包含类的实例,因此 None 仍然被拒绝(没有双关语的意思)。 gist.github.com/ThiefMaster/3c101347fd6267b5ca09
猜你喜欢
  • 2014-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-08
  • 1970-01-01
  • 2013-12-25
  • 2012-12-01
  • 1970-01-01
相关资源
最近更新 更多