关于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
相关产品推荐
相关产品推荐

