Using the source code to analyze the slice assignment in Python,
This article mainly introduces the Python slice assignment and shares it for your reference. Let's take a look at the details below:
Someone asked me this question yesterday:
T = [1, 2, 3] t [] = [7] # Thanks @ for your question, previously written as t [1:1] = 7 print t # output [1, 7, 2, 3]
I have never encountered this problem before. Does anyone assign a value to the list? However, the reason for this output is indeed worth further understanding. After all, I have also read Python source code analysis before. (Remark: It is said that some Daniel is writing a new version recently)
I want to take a look at the Python source code today and find out what the principle is.
Note:I downloaded Python2.7.6 code locally.
In Objects/listobject. c, A PyList_SetSlice function is written as follows:
intPyList_SetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v){ if (!PyList_Check(a)) { PyErr_BadInternalCall(); return -1; } return list_ass_slice((PyListObject *)a, ilow, ihigh, v);}
The useful sentence is list_ass_slice. Let's take a look at the code of this function:
Static intlist_ass_slice (PyListObject * a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject * v) {/* Because [X] DECREF can recursively invoke list operations on this list, we must postpone all [X] DECREF activity until after the list is back in its canonical shape. therefore we must allocate an additional array, 'recycle', into which we temporarily copy the items that are deleted from the list. :-(*/PyOb Ject * recycle_on_stack [8]; PyObject ** recycle = recycle_on_stack;/* will allocate more if needed */PyObject ** item; PyObject ** vitem = NULL; pyObject * v_as_SF = NULL;/* PySequence_Fast (v) */Py_ssize_t n;/* # of elements in replacement list */Py_ssize_t norig; /* # of elements in list getting replaced */Py_ssize_t d;/* Change in size */Py_ssize_t k; size_t s; int result =-1;/* guilty unt Il proved innocent */# define B (PyListObject *) v) if (v = NULL) n = 0; else {if (a = B) {/* Special case "a [I: j] = a" -- copy B first */v = list_slice (B, 0, Py_SIZE (B )); if (v = NULL) return result; result = list_ass_slice (a, ilow, ihigh, v); Py_DECREF (v); return result;} v_as_SF = PySequence_Fast (v, "can only assign an iterable"); if (v_as_SF = NULL) goto Error;/* the5fire note: the length to be assigned n */n = PySequence_Fast_GET_SIZE (v_as_SF); vitem = PySequence_Fast_ITEMS (v_as_SF);} if (ilow <0) ilow = 0; else if (ilow> Py_SIZE ()) ilow = Py_SIZE (a); if (ihigh <ilow) ihigh = ilow; else if (ihigh> Py_SIZE (a) ihigh = Py_SIZE (a); norig = ihigh-ilow; assert (norig> = 0); d = n-norig; if (Py_SIZE (a) + d = 0) {Py_XDECREF (v_as_SF); return list_clear ();} item = a-> ob_item;/* recycle the items That we are about to remove */s = norig * sizeof (PyObject *); if (s> sizeof (recycle_on_stack) {recycle = (PyObject **) PyMem_MALLOC (s ); if (recycle = NULL) {PyErr_NoMemory (); goto Error ;}} memcpy (recycle, & item [ilow], s); if (d <0) {/* Delete-d items */memmove (& item [ihigh + d], & item [ihigh], (Py_SIZE (a)-ihigh) * sizeof (PyObject *); list_resize (a, Py_SIZE (a) + d); item = a-> ob_item;} el Se if (d> 0) {/* Insert d items */k = Py_SIZE (a); if (list_resize (a, k + d) <0) goto Error; item = a-> ob_item; printf ("Key Point \ n");/* the5fire note: move all the content after the value corresponding to the value of the last part of the list to backward the assigned size according to the python code above. Here is the principle t: | 1 | 2 | 3 | move one digit behind because len ([7]) = 1 | 1 | null | 2 | 3 | shift the last two places */memmove (& item [ihigh + d], & item [ihigh], (k-ihigh) * sizeof (PyObject *);}/* the5fire Note: Assign [7] to the corresponding position in t. ilow is 1, n is 1 */for (k = 0; k <n; k ++, ilow + +) {PyObject * w = vitem [k]; Py_XINCREF (w); item [ilow] = w ;}for (k = norig-1; k> = 0; -- k) Py_XDECREF (recycle [k]); result = 0; Error: if (recycle! = Recycle_on_stack) PyMem_FREE (recycle); Py_XDECREF (v_as_SF); return result; # undef B}
After reading the answer on stackoverflow, I found that the source code is still the best explanation. The above key locations have been annotated and should be well understood.
Summary
The above is all the content of this article. I hope the content of this article will help you in your study or work. If you have any questions, please leave a message, thank you for your support.