国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

通過源碼分析Python中的切片賦值

2020-02-16 01:29:47
字體:
來源:轉載
供稿:網友

本文主要介紹的關于Python切片賦值的相關內容,分享出來供大家參考學習,下面來一起看看詳細的介紹:

昨天有同學問了我這么個問題:

t = [1, 2, 3]t[1:1] = [7] # 感謝@一往直前 的疑問,之前寫為 t[1:1] = 7了print t # 輸出 [1, 7, 2, 3]

這個問題之前還真沒遇到過,有誰會對列表這么進行賦值嗎?不過對于這個輸出結果的原因確實值得去再了解下,畢竟之前也看過《Python源碼分析》。(題外話:據說最近有大牛在寫新的版本)

想著今天有空看看Python的源碼,去了解下原理是什么。

注:我本地之前下載的是Python2.7.6的代碼,直接看的這個。

在Objects/listobject.c中有一個 PyList_SetSlice 函數,是這么寫的:

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);}

有用的一句就是 list_ass_slice ,那么再來看看這個函數的代碼:

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. :-( */ PyObject *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 until 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注:  要賦值的長度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(a))  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(a); } 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; } else if (d > 0) { /* Insert d items */  k = Py_SIZE(a);  if (list_resize(a, k+d) < 0)   goto Error;  item = a->ob_item;  printf("關鍵點/n");  /*  the5fire注:  把list對應切片后一位的值之后的所有內容向后移動所賦值的大小  按照上面的python代碼這里就是  原理的t:  |1|2|3|  后移一位,因為len([7]) = 1  |1|空|2|3|把后兩個移位  */  memmove(&item[ihigh+d], &item[ihigh],   (k - ihigh)*sizeof(PyObject *)); } /* the5fire注: 賦值操作,即把[7]賦值到t里的對應位置上 ilow是1, n是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}            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 原阳县| 济南市| 宝山区| 林甸县| 昭觉县| 吉安县| 怀远县| 香港| 防城港市| 含山县| 永登县| 左权县| 丹阳市| 全南县| 东平县| 深水埗区| 龙游县| 河东区| 平山县| 彰化县| 琼结县| 高碑店市| 乌鲁木齐市| 浏阳市| 耒阳市| 南澳县| 信宜市| 金坛市| 鄂州市| 镇巴县| 三原县| 两当县| 互助| 保亭| 霞浦县| 视频| 和田市| 当涂县| 乐业县| 刚察县| 玛纳斯县|