问题描述
在Python中(2和3).每当我们使用列表切片时,它都会返回一个新对象,例如:
In Python (2 and 3). Whenever we use list slicing it returns a new object, e.g.:
l1 = [1,2,3,4]
print(id(l1))
l2 = l1[:]
print(id(l2))
输出
>>> 140344378384464
>>> 140344378387272
如果对元组重复相同的操作,则返回相同的对象,例如:
If the same thing is repeated with tuple, the same object is returned, e.g.:
t1 = (1,2,3,4)
t2 = t1[:]
print(id(t1))
print(id(t2))
输出
>>> 140344379214896
>>> 140344379214896
如果有人能弄清为什么会发生这种情况,那将是很棒的,在我的整个Python经验中,我一直以为空切片会返回一个新对象为印象.
It would be great if someone can shed some light on why this is happening, throughout my Python experience I was under the impression empty slice returns a new object.
我的理解是,它返回的对象与元组是不可变的相同,因此没有必要为其创建新副本.但是同样,文档中也没有提到它.
My understanding is that it's returning the same object as tuples are immutable and there's no point of creating a new copy of it. But again, it's not mentioned in the documents anywhere.
推荐答案
实现可以自由地为不可变类型返回相同的实例(在CPython中,您有时可能会看到类似的字符串和整数优化).由于无法更改对象,因此在用户代码中没有任何内容需要关心它是保存唯一实例还是仅是对现有实例的另一个引用.
Implementations are free to return identical instances for immutable types (in CPython, you may sometimes see similar optimizations for strings and integers). Since the object can not be changed, there is nothing in user code that needs to care whether it holds a unique instance or just another reference to an existing instance.
您可以在C代码中找到短路这里.
You can find the short-circuit in the C code here.
static PyObject*
tuplesubscript(PyTupleObject* self, PyObject* item)
{
... /* note: irrelevant parts snipped out */
if (start == 0 && step == 1 &&
slicelength == PyTuple_GET_SIZE(self) &&
PyTuple_CheckExact(self)) {
Py_INCREF(self); /* <--- increase reference count */
return (PyObject *)self; /* <--- return another pointer to same */
}
...
这是一个实现细节,请注意, pypy 不会做同样的事情.
This is an implementation detail, note that pypy does not do the same.
这篇关于与列表切片相反,元组切片不返回新对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!