python切片取值,python中字符串可以进行切片赋值吗
有这么个问题:
t=[1,2,3]
t[1:1]=[7]
打印编号输出[1,7,2,3]谁会对列表这么进行赋值呢?但是对于这个输出结果的原因确实值得去再了解下,今天看看大蟒的源码,了解下原理是什么。
注:本地下载的是Python2.7.6的代码,直接看这个。
在Objects/listobject.c中有一个PyList_SetSlice函数,是这么写的:
(同国际组织)国际组织
PyList_SetSlice(PyObject*a,Py_ssize_tilow,Py_ssize_tihigh,PyObject*v)
{
如果(!PyList_Check(a)){
PyErr _ badin internal call();
return-1;
}
返回list _ ass _ slice((PyListObject *)a,ilow,ihigh,v);
}有用的一句就是列表_ ass _切片那么再来看看这个函数的代码:
staticint
list_ass_slice(PyListObject*a,Py_ssize_tilow,Py_ssize_tihigh,PyObject*v)
{
/*因为[X]减少了canrecursivelyinvokelistoperationson
这份名单,我们必须推迟所有[X]下降直到
afterhelistisbackinitscanonicalshape .因此
我们必须分配一个附加数组,回收,放入其中
wetemporarilycopytheitemsthataredeletedfromthe从从
list.-(*/
py object * recycle _ on _ stack[8];
py object * * recycle=recycle _ on _ stack;/* wilallocatemoreifneeded */
p对象* *项目
PyObject * * vitem=NULL
py object * v _ as _ SF=NULL/* py sequence _ Fast(v)*/
铌
sp;Py_ssize_tn;/*#ofelementsinreplacementlist*/
Py_ssize_tnorig;/*#ofelementsinlistgettingreplaced*/
Py_ssize_td;/*Changeinsize*/
Py_ssize_tk;
size_ts;
intresult=-1;/*guiltyuntilprovedinnocent*/
#defineb((PyListObject*)v)
if(v==NULL)
n=0;
else{
if(a==b){
/*Specialcase"a[i:j]=a"--copybfirst*/
v=list_slice(b,0,Py_SIZE(b));
if(v==NULL)
returnresult;
result=list_ass_slice(a,ilow,ihigh,v);
Py_DECREF(v);
returnresult;
}
v_as_SF=PySequence_Fast(v,"canonlyassignaniterable");
if(v_as_SF==NULL)
gotoError;
/*
要赋值的长度n
*/
n=PySequence_Fast_GET_SIZE(v_as_SF);
vitem=PySequence_Fast_ITEMS(v_as_SF);
}
if(ilow<0)
ilow=0;
elseif(ilow>Py_SIZE(a))
ilow=Py_SIZE(a);
if(ihigh<ilow)
ihigh=ilow;
elseif(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);
returnlist_clear(a);
}
item=a->ob_item;
/*recycletheitemsthatweareabouttoremove*/
s=norig*sizeof(PyObject*);
if(s>sizeof(recycle_on_stack)){
recycle=(PyObject**)PyMem_MALLOC(s);
if(recycle==NULL){
PyErr_NoMemory();
gotoError;
}
}
memcpy(recycle,&item[ilow],s);
if(d<0){/*Delete-ditems*/
memmove(&item[ihigh+d],&item[ihigh],
(Py_SIZE(a)-ihigh)*sizeof(PyObject*));
list_resize(a,Py_SIZE(a)+d);
item=a->ob_item;
}
elseif(d>0){/*Insertditems*/
k=Py_SIZE(a);
if(list_resize(a,k+d)<0)
gotoError;
item=a->ob_item;
printf("关键点\n");
/*
把list对应切片后一位的值之后的所有内容向后移动所赋值的大小
按照上面的python代码这里就是
原理的t:
123
后移一位,因为len([7])=1
1空23把后两个移位
*/
memmove(&item[ihigh+d],&item[ihigh],
(k-ihigh)*sizeof(PyObject*));
}
/*
赋值操作,即把[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);
returnresult;
#undefb
}源码内有详细注释,编程问题的研究最好的解释还是源码。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。