首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >序列片的Python恒等式

序列片的Python恒等式
EN

Stack Overflow用户
提问于 2022-11-15 19:44:05
回答 1查看 43关注 0票数 0

我注意到了一些具有“身份”的东西,即由id()返回的某些序列类型的切片的值,这些片段是我根本无法理解的。我在列表和字符串中看到了它,这使我认为它与CPython中的序列或片的实现有关。

3.数据模型- Python 3.11.0文档所涵盖的那样

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

代码语言:javascript
复制
>>> 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

到目前为止,没有什么不寻常之处,因为我希望看到列表对象的不同内存地址,而不是从列表中返回的单个元素。但是,当我查看列表的切片时,内存地址对我来说没有意义:

代码语言:javascript
复制
>>> 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()返回内存地址到底是什么?而后续,为什么第一和第二片的身份不同,但之后的切片是相同的,包括第一片?

EN

回答 1

Stack Overflow用户

发布于 2022-11-16 08:00:30

这种行为是因为Cpython的优化。让我们从

代码语言:javascript
复制
>>> l[2:]

切片一个列表总是创建一个新列表。。因为分配和释放列表对象是一项昂贵的操作,所以python解释器会跟踪PyListObject

代码语言:javascript
复制
/* Empty list reuse scheme to save calls to malloc and free */
#ifndef PyList_MAXFREELIST
#  define PyList_MAXFREELIST 80
#endif

struct _Py_list_state {
#if PyList_MAXFREELIST > 0
    PyListObject *free_list[PyList_MAXFREELIST];
    int numfree;
#endif
};

所以当你要求一个新的名单(记住切片也创建了一个新的列表)是从此免费列表中送达(如果可用的话)。

代码语言:javascript
复制
if (PyList_MAXFREELIST && state->numfree) {
        state->numfree--;
        op = state->free_list[state->numfree];
        OBJECT_STAT_INC(from_freelist);
        _Py_NewReference((PyObject *)op);
}

由于您要立即丢弃list对象,所以python解释器调用list_dealloc,这将恢复这个free_list

代码语言:javascript
复制
if (state->numfree < PyList_MAXFREELIST && PyList_CheckExact(op)) {
        state->free_list[state->numfree++] = op;
        OBJECT_STAT_INC(to_freelist);
}

当您下次进行切片时,实际上是从free_list获得对同一个list对象的引用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74451312

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档