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

Python变量内存地址分配机制及赋值行为技术疑问

Python变量内存分配与列表append机制答疑

问题背景

用户基于三个测试案例,对Python的变量内存分配、列表append机制存在疑问,先明确三个测试的代码与结果:

测试1:循环生成不同值的变量

ls = []
for i in range(0,10):
    a = 1 + i
    print(id(a))
    ls.append(a)

ls
  • 输出:每次id(a)均不相同
  • 最终列表:[1,2,...,10]

测试2:循环赋值相同值的变量

ls = []
for i in range(0,10):
    a = 1
    print(id(a))
    ls.append(a)

ls
  • 输出:每次id(a)始终一致
  • 最终列表:由10个1组成的列表

测试3:赋值后修改变量

ls = []
for i in range(0,10):
    a = 1
    print(id(a))
    ls.append(a)
    a = 10
    print(id(a))

ls
  • 输出:每次循环先输出1的地址,后输出10的地址
  • 最终列表:仍为10个1

核心疑问解答

1. Python如何为变量分配内存地址?

Python中的变量本质是对内存中对象的引用,并非直接存储值。执行赋值语句时,Python会先检查内存中是否存在对应值的对象:

  • 若存在,让变量直接指向该对象的地址;
  • 若不存在,才会创建新的对象,再让变量指向新对象的地址。

针对小整数(通常范围是-5到256,具体依赖Python实现),Python会提前在内存中创建并缓存这些对象,也就是“小整数池”机制。测试2中每次a=1,变量a都会指向缓存好的同一个1对象,因此id(a)始终相同;测试1中a=1+i生成的是1到10的不同数值,每个数值对应不同的缓存对象,所以id(a)每次都不同。

2. 为什么修改变量a的值不会影响列表中的元素?

列表ls中存储的是对象的引用,而非变量a的引用。执行ls.append(a)时,是把a当前指向的对象地址存入列表。后续修改a=10,只是让变量a转而指向值为10的新对象,并不会改变列表中已存储的、指向1的引用。

简单来说:你把写着“1的地址”的纸条放进列表,之后自己手里的纸条换成“10的地址”,但列表里的纸条还是原来那一张,所以列表元素不会变化。

3. 为什么相同值复用地址、修改值则更换地址?

  • 相同值复用地址:源于Python的对象缓存机制,比如小整数池、字符串驻留(部分字符串会被缓存)。这种机制能节省内存,避免重复创建相同值的对象,所以测试2中每次赋值a=1都会复用同一地址。
  • 修改值则更换地址:Python中的整数、字符串属于不可变对象,无法直接修改原对象的值。当你试图“修改”变量的值时,实际是创建一个新的对象,再让变量指向这个新对象的地址。比如测试3中a=10,是新建了值为10的对象,a转而指向新地址,原1对象未被修改,列表中的引用也保持指向1的地址。

内容的提问来源于stack exchange,提问作者Johnny C.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 17:03:17