En Python 3. * my_list[:]
es el azúcar sintáctico para type(my_list).__getitem__(mylist, slice_object)
donde: slice_object
es un objeto de corte construido a partir my_list
de los atributos (longitud) y la expresión [:]
. Los objetos que se comportan de esta manera se denominan subscriptables en el modelo de datos de Python, ver aquí . Para listas y tuplas __getitem__
es un método incorporado.
En CPython, y para listas y tuplas, __getitem__
se interpreta mediante la operación de código de bytes BINARY_SUBSCR
que se implementa para las tuplas aquí y para las listas aquí .
En el caso de las tuplas, al recorrer el código, verá que en este bloque de código , static PyObject*
tuplesubscript(PyTupleObject* self, PyObject* item)
devolverá una referencia al mismo PyTupleObject
que obtuvo como argumento de entrada, si el elemento es de tipo PySlice
y el segmento se evalúa como la tupla completa.
static PyObject*
tuplesubscript(PyTupleObject* self, PyObject* item)
{
/* checks if item is an index */
if (PyIndex_Check(item)) {
...
}
/* else it is a slice */
else if (PySlice_Check(item)) {
...
/* unpacks the slice into start, stop and step */
if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
return NULL;
}
...
}
/* if we start at 0, step by 1 and end by the end of the tuple then !! look down */
else if (start == 0 && step == 1 &&
slicelength == PyTuple_GET_SIZE(self) &&
PyTuple_CheckExact(self)) {
Py_INCREF(self); /* increase the reference count for the tuple */
return (PyObject *)self; /* and return a reference to the same tuple. */
...
}
Ahora examina el código static PyObject *
list_subscript(PyListObject* self, PyObject* item)
y comprueba por sí mismo que, sea cual sea el segmento, siempre se devuelve un nuevo objeto de lista.
l2 = tuple(iter(l1))
omite la optimizaciónPyTuple_GetSlice
se documentó de manera incorrecta después de ver su pregunta. Los documentos ahora se han solucionado (este era el problema bpo38557 ).