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

Python序列切片的id()返回值疑问:内存地址与重复身份解析

列表切片的id()返回值困惑解析

问题背景

根据Python 3.11.0文档《3. Data model》的CPython实现细节:

CPython实现细节:在CPython中,id(x)是x存储的内存地址。

测试列表单个元素的id时,结果符合预期:

>>> l = list(range(10))
>>> l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> l[3]
3
>>> l[7]
7
>>> id(l)
1931973192256
>>> id(l[3])
1931941276016
>>> id(l[7])
1931941276144

列表对象与单个元素的内存地址各不相同,这符合预期。但切片操作的id结果却出现了反常现象:

>>> l[2:]
[2, 3, 4, 5, 6, 7, 8, 9]
>>> l[5:]
[5, 6, 7, 8, 9]
>>> l[3:9]
[3, 4, 5, 6, 7, 8]
>>> l[:-6]
[0, 1, 2, 3]
>>> id(l[2:])
2813785568448
>>> id(l[5:])
2813784049664
>>> id(l[3:9])
2813784049664
>>> id(l[:-6])
2813784049664
>>> id(l[2:])
2813784049664

首次切片的id与后续所有切片(包括重复执行首次切片操作)的id完全相同,无论切片内容如何。

疑问

  • 对列表切片时,id()返回的具体是哪个对象的内存地址?
  • 为何首次与第二次切片的id不同,但后续切片(含首次切片)的id均相同?

核心解析

1. 切片返回的是新创建的列表对象

列表的切片操作l[a:b]每次都会生成一个全新的列表对象,这个新列表包含原列表对应范围元素的引用。id()返回的就是这个新创建的列表对象的内存地址。

2. 临时对象的内存复用机制

出现id重复的本质是CPython的临时对象内存复用策略:

  • 在交互式环境中,执行id(l[2:])时,第一个切片生成的新列表是临时对象——id()执行完毕后,这个对象没有任何变量引用它,会被Python的垃圾回收机制标记为可回收。
  • 后续执行切片操作时,新创建的列表会复用之前被回收的临时对象的内存空间,因此它们的id()会和之前的临时对象一致。
  • 首次切片的id与后续不同,是因为此时没有可复用的内存空间,Python需要分配一块新内存;当第一次切片的对象被回收后,后续切片就可以复用这块内存,所以id全部相同。

补充说明

这种现象在交互式环境中更容易观察到。如果在脚本中用变量保存切片结果(比如slice1 = l[2:]),该对象会被持续引用,内存不会被回收,后续切片的id就会与它不同。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 18:20:58