You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于Python del保留字的原理及使用疑问求助

Python中del保留字的原理与常见疑问解析

一、链表删除中的del误区

先给出链表的通用框架代码:

class Node:
    def __init__(self, data, nxt=None):
        self.data = data
        self.nxt = nxt
        
class NodeMgmt:
    def __init__(self, data):
        self.head = Node(data)
        
    def add(self, data):
        current_node = self.head
        while current_node.nxt is not None:
            current_node = current_node.nxt
        current_node.nxt = Node(data)
        
    def desc(self):
        current_node = self.head
        while current_node:
            print(current_node.data)
            current_node = current_node.nxt

有问题的delete实现及执行结果

下面这个delete方法执行后,链表元素并未被删除:

def delete(self,data):
    current_node = self.head          
    while current_node.data != data:
        current_node = current_node.nxt
    del current_node

执行代码:

lnk = NodeMgmt(1)
lnk.add(2)
lnk.desc() # 输出:1 2
lnk.delete(2)
lnk.desc() # 输出仍为:1 2

正确的链表删除实现

正确的做法是修改前驱节点的nxt指针,而非直接删除节点变量:

def delete(self,data):
    current_node = self.head
    current_node_parent = self.head
    while current_node:
        if current_node.data != data: 
            current_node_parent = current_node
            current_node = current_node.nxt
        else:
            break
            
    current_node_parent.nxt = current_node.nxt

二、列表中的del疑问

以下代码中,执行del li1后,li并未被删除:

li = [1,2,3]
li1 = li
li1.append(1)
print(li) # 输出:[1,2,3,1]
del li1[2:] 
print(li) # 输出:[1,2]
del li1
print(li) # 输出:[1,2] 为什么li没被删除?

三、del的核心原理

要搞懂上述问题,必须明确del操作的对象是变量,不是变量指向的内存对象:

  • Python中所有变量都是对内存中对象的引用,一个对象可以被多个变量同时引用。
  • del的作用是解除变量与对象之间的引用绑定关系,只有当该对象的引用计数变为0时,Python的垃圾回收机制才会回收这个对象的内存空间。

链表问题的原因

在错误的delete方法中:

  • current_node只是一个临时变量,它指向了链表中data为2的Node对象,但链表的前驱节点(data为1的Node)的nxt指针仍然指向这个Node对象。
  • 执行del current_node只是解除了current_node变量与该Node对象的引用,而链表结构中对该对象的引用还存在(前驱节点的nxt),所以对象不会被回收,链表结构也没有变化。
  • 正确的做法是修改前驱节点的nxt,切断链表对该Node对象的引用,这样当没有其他变量引用它时,对象才会被垃圾回收。

列表问题的原因

  • li和li1都是对同一个列表对象的引用,li1.append(1)和del li1[2:]都是直接修改这个共享的列表对象,所以li的内容会跟着变化。
  • 执行del li1只是解除了li1与列表对象的引用绑定,但li仍然引用着这个列表对象,该对象的引用计数不为0,所以不会被回收,li自然还能访问到它。

内容的提问来源于stack exchange,提问作者KimGyeongMin-KR

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 23:25:22