web-dev-qa-db-ja.com

タプルのスライスはリストのスライスとは対照的に新しいオブジェクトを返さない

Python(2 and 3)です。リストスライスを使用すると、常に新しいオブジェクトが返されます。例:

l1 = [1,2,3,4]
print(id(l1))
l2 = l1[:]
print(id(l2))

出力

>>> 140344378384464
>>> 140344378387272

同じことをタプルで繰り返すと、同じオブジェクトが返されます。例:

t1 = (1,2,3,4)
t2 = t1[:]
print(id(t1))
print(id(t2))

出力

>>> 140344379214896
>>> 140344379214896

私のPythonの経験全体を通して、空のスライスが新しいオブジェクトを返すという印象を受けました。).

私の理解では、タプルは不変であるのと同じオブジェクトを返し、その新しいコピーを作成する意味はありません。しかし、繰り返しになりますが、ドキュメントのどこにも記載されていません。

12
Vijay Jangir

Python 3. * _my_list[:]_はtype(my_list).__getitem__(mylist, slice_object)の構文糖です。ここで:_slice_object_は_my_list_の属性から構築されたスライスオブジェクトです(長さ)と式_[:]_。このように動作するオブジェクトは、Pythonデータモデルで添字可能と呼ばれます ここ を参照してください。リストとタプルについて___getitem___は組み込みメソッドです。

CPythonでは、リストとタプルの場合、___getitem___はバイトコード演算_BINARY_SUBSCR_によって解釈され、タプル ここに およびリスト ここに に実装されます=。

タプルの場合、コードを歩くと、 このコードブロックstatic PyObject* tuplesubscript(PyTupleObject* self, PyObject* item)が入力として取得したのと同じPyTupleObjectへの参照を返すことがわかります引数。項目のタイプがPySliceであり、スライスがタプル全体に評価される場合。

_    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. */
        ...
}
_

次に、static PyObject * list_subscript(PyListObject* self, PyObject* item)のコードを調べて、スライスが何であれ、新しいリストオブジェクトが常に返されることを確認します。

1
Fakher Mokadem

これについては不明ですが、Pythonは、同じオブジェクトへの新しいポインタを提供して、コピーを回避するためにタプルが同一であるため(オブジェクトはタプルであるため、不変です)のようです。

0
michotross