python切片取值,python中字符串可以进行切片赋值吗

  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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: