日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python列表切片赋值_Python中对切片赋值原理分析

發布時間:2024/7/19 python 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python列表切片赋值_Python中对切片赋值原理分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

有這么個問題::t?=?[1,?2,?3]

t[1:1]?=?[7]

print?t??#?輸出?[1,?7,?2,?3]

誰會對列表這么進行賦值呢?但是對于這個輸出結果的原因確實值得去再了解下,今天看看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;

/*

要賦值的長度n

*/

n?=?PySequence_Fast_GET_SIZE(v_as_SF);

vitem?=?PySequence_Fast_ITEMS(v_as_SF);

}

if?(ilow?

ilow?=?0;

else?if?(ilow?>?Py_SIZE(a))

ilow?=?Py_SIZE(a);

if?(ihigh?

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?

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)?

goto?Error;

item?=?a->ob_item;

printf("關鍵點\n");

/*

把list對應切片后一位的值之后的所有內容向后移動所賦值的大小

按照上面的python代碼這里就是

原理的t:

|1|2|3|

后移一位,因為len([7])?=?1

|1|空|2|3|把后兩個移位

*/

memmove(&item[ihigh d],?&item[ihigh],

(k?-?ihigh)*sizeof(PyObject?*));

}

/*

賦值操作,即把[7]賦值到t里的對應位置上

ilow是1,?n是1

*/

for?(k?=?0;?k?

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

}

源碼內有詳細注釋,編程問題的研究最好的解釋還是源碼。

總結

以上是生活随笔為你收集整理的python列表切片赋值_Python中对切片赋值原理分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。