国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

腳本之家,腳本語言編程技術(shù)及教程分享平臺!
分類導(dǎo)航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Python - 通過源碼分析Python中的切片賦值

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

2020-10-08 14:51the5fire Python

因?yàn)榻?jīng)常取指定索引范圍的操作,用循環(huán)十分繁瑣,因此,Python提供了切片(Slice)操作符,能大大簡化這種操作。而下面這篇文章則通過源碼給大家分析介紹了Python中切片賦值的相關(guān)資料,需要的朋友可以參考學(xué)習(xí),下面來一起看

本文主要介紹的關(guān)于Python切片賦值的相關(guān)內(nèi)容,分享出來供大家參考學(xué)習(xí),下面來一起看看詳細(xì)的介紹:

昨天有同學(xué)問了我這么個(gè)問題:

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

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

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

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

在Objects/listobject.c中有一個(gè) PyList_SetSlice 函數(shù),是這么寫的:

?
1
2
3
4
5
6
7
8
9
int
PyList_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 ,那么再來看看這個(gè)函數(shù)的代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
static int
list_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("關(guān)鍵點(diǎn)\n");
  /*
  the5fire注:
  list對應(yīng)切片后一位的值之后的所有內(nèi)容向后移動(dòng)所賦值的大小
  按照上面的python代碼這里就是
  原理的t:
  |1|2|3|
  后移一位,因?yàn)?/code>len([7]) = 1
  |1|空|2|3|把后兩個(gè)移位
  */
  memmove(&item[ihigh+d], &item[ihigh],
   (k - ihigh)*sizeof(PyObject *));
 }
 /*
 the5fire注:
 賦值操作,即把[7]賦值到t里的對應(yīng)位置上
 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
}

看了知乎,stackoverflow上的解答,發(fā)現(xiàn)源碼還是最好的解釋。上述關(guān)鍵位置已經(jīng)加了注釋,應(yīng)該很好理解。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對服務(wù)器之家的支持。

原文鏈接:https://www.the5fire.com/python-slice-assignment-analyse-souce-code.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美在线操 | 韩国av一区二区 | 韩日av在线| 日韩婷婷| 黄色片免费在线观看视频 | 国产在线精品一区 | 色888www视频在线观看 | 久久久亚洲国产美女国产盗摄 | 久久综合久久综合久久 | 中文av一区 | 日本一区二区免费在线观看 | 中文字幕高清在线 | 国产在线一区二区三区 | 亚洲黄页 | 韩日一区二区三区 | 欧美一区二区激情视频 | 国产高清精品在线 | 国产成人毛片 | 日韩精品一区二区在线 | 午夜久久久 | www乱| 国产一区二区视频在线观看 | 在线国产视频观看 | 欧美日韩一区二 | 麻豆产精国品免费入口 | 91香蕉| 精品欧美一区二区三区久久久 | 国产成人综合网 | 欧美福利二区 | 国产激情精品视频 | 国产三级精品在线 | 中文字幕av一区二区 | 日韩国产一区二区三区 | 国产精品美女久久久久久免费 | av影院在线观看 | 草樱av| 成人自拍视频 | 久草在线资源福利站 | 99伊人 | 国产日韩在线视频 | 草草视频在线观看 |