本文主要介绍的关于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 函数,是这么写的:
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 ,那么再来看看这个函数的代码:
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("关键点\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 }
看了知乎,stackoverflow上的解答,发现源码还是最好的解释。上述关键位置已经加了注释,应该很好理解。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
华山资源网 Design By www.eoogi.com
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
华山资源网 Design By www.eoogi.com
暂无评论...
稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!
昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。
这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。
而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?
更新日志
2024年11月19日
2024年11月19日
- 2024罗志祥《舞狀元》[FLAC/MP3][1G]
- 张美玲侯俊辉1999-福建情歌对唱[南方][WAV+CUE]
- 江希文.1994-伝说少女(饿狼伝说动画原声大碟)【嘉音】【WAV+CUE】
- 黄思婷2020-风中泪[豪记][WAV+CUE]
- 刘韵.1998-DENON.MASTERSONIC系列【EMI百代】【WAV+CUE】
- 群星.2024-你的谎言也动听影视原声带【韶愔音乐】【FLAC分轨】
- 群星.2003-难忘的影视金曲·港台篇【正大国际】【WAV+CUE】
- 试音天碟《原音HQCD》风林 [WAV+CUE][1.1G]
- 李思思《喜欢你》头版限量编号24K金碟[低速原抓WAV+CUE][1.1G]
- 王杰《这场游戏那场梦》 台湾华纳首版 [WAV+CUE][1G]
- 群星2005-《影视红声》2CD香港首版[WAV+CUE]
- 群星2017《聆听中国.风华国乐》试音碟[WAV+CUE]
- 群星2016-《环球词选.潘源良》环球[WAV+CUE]
- 张惠妹《爱的力量》10年情歌最精选 2CD[WAV+CUE][1.1G]
- 群星2009《LOVE TV情歌精选VOL.2》香港首版[WAV+CUE][1.1G]