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

Python中delete_head1与delete_head2函数差异及变量绑定原理问询

Python列表函数修改差异的原理解析

我们来看以下两个Python函数:

def delete_head1(t):
    #t[:] = t[1:]
    t = t[1:]
def delete_head2(t):
    t[:] = t[1:]
    #t = t[1:]

执行下面的代码会得到完全不同的结果:

测试1:

k=[1,2,3]
delete_head1(k)
print(k)  # 输出 [1,2,3]

测试2:

k=[1,2,3]
delete_head2(k)
print(k)  # 输出 [2,3]

为什么第二个函数能修改输入的列表,第一个却不行?核心疑问点包括:

  • 第一个函数里的t变成了局部变量,为什么第二个函数的t没有?
  • 执行t = t[1:]时,解释器能识别等号后的t,却把等号前的t当成新局部变量?而t[:] = t[1:]时,两个t都指向原列表?Python背后的规则是什么?

核心区别:变量赋值 vs 原地修改对象

Python里的变量本质是对象的引用,函数参数传递的也是这个引用。我们拆解两个函数的执行逻辑:

1. delete_head1的执行过程

  • 函数调用时,局部变量t一开始和外部的k指向同一个列表对象[1,2,3]。
  • 当执行t = t[1:]时,t[1:]会生成一个新的列表切片[2,3],赋值操作=会把局部变量t重新绑定到这个新列表上。
  • 此时外部的k依然指向原来的[1,2,3],所以打印k不会有变化。这里的t确实变成了函数内部的局部变量,因为它的引用指向已经被替换,和原参数解绑了。

2. delete_head2的执行过程

  • 同样,局部变量t一开始指向外部k对应的列表[1,2,3]。
  • 执行t[:] = t[1:]时,这不是变量赋值,而是切片赋值操作——它直接修改t指向的原列表对象:把原列表的所有元素替换成t[1:]的内容(也就是[2,3])。
  • 这个操作没有改变t的引用指向,只是修改了它指向的对象本身。因为外部的k和t指向同一个对象,所以打印k时会看到修改后的结果。

关于变量识别的疑问解答

  • 对于t = t[1:]:等号右边的t是函数参数传入的原引用(指向原列表),但等号左边的t在赋值操作时,会被Python标记为局部变量——只要在函数内部对变量进行赋值,Python就会认为这是一个新的局部变量,和原来的参数引用解绑。
  • 对于t[:] = t[1:]:这里的两个t都是指向原列表的引用。切片赋值是调用列表对象的原地修改方法,本质是对t指向的对象进行操作,没有改变t本身的引用,所以t始终是函数参数传入的那个引用,不会变成新的局部变量。

Python的核心原则

Python遵循**“变量是对象的引用”**的核心规则:

  • 赋值语句(=)的作用是改变变量的引用指向,让变量指向另一个对象。
  • 原地操作(比如切片赋值、append()、pop()等)的作用是修改变量指向的对象本身,不会改变变量的引用。

内容的提问来源于stack exchange,提问作者onyourmark

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 11:20:31