电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

Python源碼解析之List

瀏覽:2日期:2022-06-18 17:24:22
目錄一、列表結(jié)構(gòu)體二、創(chuàng)建列表三、添加元素四、移除元素五、清空六、銷毀一、列表結(jié)構(gòu)體

創(chuàng)建列表C語言底層的結(jié)構(gòu)體

lists = []list.append(’name’)list.append(’age’)list.append(’grade’)

typedef struct{struct _object *_ob_next;struct _object *_ob_prev; // python內(nèi)部將對象放在鏈表進行內(nèi)存管理Py_ssize_t ob_refcnt;// 引用計數(shù)器,就是多少變量用了它PyObject **ob_item;// 指針的指針,存列表的元素Py_ssize_t ob_size;// 已有元素個數(shù)Py_ssize_t allocated;// 列表容量,可容納個數(shù)} PyListObject;

c源碼來自 listobject.c

二、創(chuàng)建列表

name_list = [ ]

PyObject *PyList_New(Py_ssize_t size){ PyListObject *op; size_t nbytes;#ifdef SHOW_ALLOC_COUNT static int initialized = 0; if (!initialized) {Py_AtExit(show_alloc);initialized = 1; }#endif // 緩存機制 if (size < 0) {PyErr_BadInternalCall();return NULL; } /* Check for overflow without an actual overflow, * which can cause compiler to optimise out */ if ((size_t)size > PY_SIZE_MAX / sizeof(PyObject *))return PyErr_NoMemory(); nbytes = size * sizeof(PyObject *); if (numfree) {numfree--;op = free_list[numfree];_Py_NewReference((PyObject *)op);#ifdef SHOW_ALLOC_COUNTcount_reuse++;#endif } else {op = PyObject_GC_New(PyListObject, &PyList_Type);if (op == NULL) return NULL;Py#ifdef SHOW_ALLOC_COUNTcount_alloc++;#endif } if (size <= 0)op->ob_item = NULL; else {op->ob_item = (PyObject **) PyMem_MALLOC(nbytes);if (op->ob_item == NULL) { Py_DECREF(op); return PyErr_NoMemory();}memset(op->ob_item, 0, nbytes); } Py_SIZE(op) = size; // 元素個數(shù) op->allocated = size; // 容量 _PyObject_GC_TRACK(op); //放到雙向鏈表進行維護 return (PyObject *) op; //返回列表的指針}三、添加元素

list中插入一個元素時,擴容連續(xù)的內(nèi)存地址(容量),在內(nèi)存創(chuàng)建需要插入的內(nèi)容p,將地址*p放入list的空間中,所以,PyListObject的ob_item是指針的指針

Python源碼解析之List

擴容的曲線一般就是0,4,8,16,24…

// 添加元素static intapp1(PyListObject *self, PyObject *v){ // 獲取實際元素個數(shù) Py_ssize_t n = PyList_GET_SIZE(self); assert (v != NULL); if (n == PY_SSIZE_T_MAX) {PyErr_SetString(PyExc_OverflowError, 'cannot add more objects to list');return -1; } // 計算當前容量和內(nèi)部元素個數(shù) // 直接添加元素/擴容添加 if (list_resize(self, n+1) == -1)return -1; // 將元素添加到ob_item,v Py_INCREF(v); PyList_SET_ITEM(self, n, v); return 0;} 擴容

// 擴容機制 // newsize: 已存在元素個數(shù)+1static intlist_resize(PyListObject *self, Py_ssize_t newsize){ PyObject **items; size_t new_allocated; Py_ssize_t allocated = self->allocated; // 當前的容量 // 1,容量大于個數(shù) // 2,個數(shù)大于容量的一半(容量足夠且沒有內(nèi)存浪費) if (allocated >= newsize && newsize >= (allocated >> 1)) {assert(self->ob_item != NULL || newsize == 0);Py_SIZE(self) = newsize;return 0; } /* * The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ... */ // 擴容機制的算法 new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6); /* check for integer overflow */ if (new_allocated > PY_SIZE_MAX - newsize) {PyErr_NoMemory();return -1; } else {new_allocated += newsize; } if (newsize == 0)new_allocated = 0; // 擴容/縮容(涉及原來元素的遷移) items = self->ob_item; if (new_allocated <= (PY_SIZE_MAX / sizeof(PyObject *)))PyMem_RESIZE(items, PyObject *, new_allocated); elseitems = NULL; if (items == NULL) {PyErr_NoMemory();return -1; } // 賦值,更新個數(shù)和容量 self->ob_item = items; Py_SIZE(self) = newsize; self->allocated = new_allocated; return 0;}四、移除元素

list.pop()刪除最后一個元素只需要修改size,不需要清除數(shù)據(jù),下次append可以直接覆蓋這個位置指定索引位置移除后,向前補位

static PyObject *listpop(PyListObject *self, PyObject *args){ Py_ssize_t i = -1; PyObject *v; int status; if (!PyArg_ParseTuple(args, '|n:pop', &i))return NULL; if (Py_SIZE(self) == 0) {/* Special-case most common failure cause */PyErr_SetString(PyExc_IndexError, 'pop from empty list');return NULL; } if (i < 0)i += Py_SIZE(self); if (i < 0 || i >= Py_SIZE(self)) {PyErr_SetString(PyExc_IndexError, 'pop index out of range');return NULL; } v = self->ob_item[i]; // 刪除最后一個,僅改變size if (i == Py_SIZE(self) - 1) {status = list_resize(self, Py_SIZE(self) - 1);assert(status >= 0);return v; /* and v now owns the reference the list had */ } Py_INCREF(v); // 不是最后一個,需要移動數(shù)據(jù)位置 status = list_ass_slice(self, i, i+1, (PyObject *)NULL); assert(status >= 0); /* Use status, so that in a release build compilers don’t * complain about the unused name. */ (void) status; return v;}五、清空

list.clear()

static intlist_clear(PyListObject *a){ Py_ssize_t i; PyObject **item = a->ob_item; if (item != NULL) {i = Py_SIZE(a);// 各個元素設置為空Py_SIZE(a) = 0;a->ob_item = NULL;a->allocated = 0;// 引用計數(shù)器-1while (--i >= 0) { Py_XDECREF(item[i]);}PyMem_FREE(item); } return 0;}六、銷毀

del list

銷毀列表對象的操作將列表的引用計數(shù)-1引用計數(shù)>0,還有應用的話不做操作引用計數(shù)=0,沒人使用

處理列表的元素,將所有引用計數(shù)-1(GC回收0計數(shù)) ob_item=0,ob_size=0,ob_allocated=0 將列表從雙向鏈表移除,可以銷毀 為了提高效率,Python結(jié)束期在內(nèi)部為free_list緩存80個list,存放無使用的list,再創(chuàng)建的時候直接從緩存中拿來初始化。如果已經(jīng)存了80個,del 的時候直接在內(nèi)存中銷毀對象

static voidlist_dealloc(PyListObject *op){ Py_ssize_t i; // 判斷引用計數(shù)是否為0 PyObject_GC_UnTrack(op); Py_TRASHCAN_SAFE_BEGIN(op) if (op->ob_item != NULL) {i = Py_SIZE(op);while (--i >= 0) { Py_XDECREF(op->ob_item[i]);}PyMem_FREE(op->ob_item); } // free_list沒有80個的話緩存這個list if (numfree < PyList_MAXFREELIST && PyList_CheckExact(op))free_list[numfree++] = op; elsePy_TYPE(op)->tp_free((PyObject *)op); Py_TRASHCAN_SAFE_END(op)}

就是說創(chuàng)建列表時,實際上不會直接開辟內(nèi)存,而是先看看free_list

# 兩次list的地址相同>>> list1=[1,2,3]>>> id(list1)69070216L>>> del list1>>> list2=[0,0,0]>>> id(list2)69303304L>>>

到此這篇關于Python源碼解析之List的文章就介紹到這了,更多相關Python List內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持好吧啦網(wǎng)!

標簽: Python 編程
相關文章:
主站蜘蛛池模板: 无菌实验室规划装修设计-一体化实验室承包-北京洁净净化工程建设施工-北京航天科恩实验室装备工程技术有限公司 | 连栋温室大棚建造厂家-智能玻璃温室-薄膜温室_青州市亿诚农业科技 | 压力控制器,差压控制器,温度控制器,防爆压力控制器,防爆温度控制器,防爆差压控制器-常州天利智能控制股份有限公司 | 硅PU球场、篮球场地面施工「水性、环保、弹性」硅PU材料生产厂家-广东中星体育公司 | 鲸鱼视觉 -数字展厅多媒体互动展示制作公司| 江苏齐宝进出口贸易有限公司 | 档案密集架_电动密集架_移动密集架_辽宁档案密集架-盛隆柜业厂家现货批发销售价格公道 | 黄石东方妇产医院_黄石妇科医院哪家好_黄石无痛人流医院 | 深圳市简易检测技术有限公司| 蒸压釜-陶粒板隔墙板蒸压釜-山东鑫泰鑫智能装备有限公司 | 长江船运_国内海运_内贸船运_大件海运|运输_船舶运输价格_钢材船运_内河运输_风电甲板船_游艇运输_航运货代电话_上海交航船运 | 防腐储罐_塑料储罐_PE储罐厂家_淄博富邦滚塑防腐设备科技有限公司 | 纯水设备_苏州皙全超纯水设备水处理设备生产厂家 | 礼堂椅厂家|佛山市艺典家具有限公司| 无缝方管|无缝矩形管|无缝方矩管|无锡方管厂家 | 活性炭厂家-蜂窝活性炭-粉状/柱状/果壳/椰壳活性炭-大千净化-活性炭 | 危废处理系统,水泥厂DCS集散控制系统,石灰窑设备自动化控制系统-淄博正展工控设备 | 市政路灯_厂家-淄博信达电力科技有限公司| 净化板-洁净板-净化板价格-净化板生产厂家-山东鸿星新材料科技股份有限公司 | 北京翻译公司_同传翻译_字幕翻译_合同翻译_英语陪同翻译_影视翻译_翻译盖章-译铭信息 | 禹城彩钢厂_钢结构板房_彩钢复合板-禹城泰瑞彩钢复合板加工厂 | 耐高温风管_耐高温软管_食品级软管_吸尘管_钢丝软管_卫生级软管_塑料波纹管-东莞市鑫翔宇软管有限公司 | 广西正涛环保工程有限公司【官网】 | 组织研磨机-高通量组织研磨仪-实验室多样品组织研磨机-东方天净 传递窗_超净|洁净工作台_高效过滤器-传递窗厂家广州梓净公司 | 印刷人才网 印刷、包装、造纸,中国80%的印刷企业人才招聘选印刷人才网! | 附着力促进剂-尼龙处理剂-PP处理剂-金属附着力处理剂-东莞市炅盛塑胶科技有限公司 | 丙烷/液氧/液氮气化器,丙烷/液氧/液氮汽化器-无锡舍勒能源科技有限公司 | 智慧物联网行业一站式解决方案提供商-北京东成基业 | 理化生实验室设备,吊装实验室设备,顶装实验室设备,实验室成套设备厂家,校园功能室设备,智慧书法教室方案 - 东莞市惠森教学设备有限公司 | 亮化工程,亮化设计,城市亮化工程,亮化资质合作,长沙亮化照明,杰奥思【官网】 | 温州食堂承包 - 温州市尚膳餐饮管理有限公司 | 世纪豪门官网 世纪豪门集成吊顶加盟电话 世纪豪门售后电话 | TwistDx恒温扩增-RAA等温-Jackson抗体-默瑞(上海)生物科技有限公司 | 坏男孩影院-提供最新电影_动漫_综艺_电视剧_迅雷免费电影最新观看 | 南京兰江泵业有限公司-水解酸化池潜水搅拌机-絮凝反应池搅拌机-好氧区潜水推进器 | 水热合成反应釜-防爆高压消解罐-西安常仪仪器设备有限公司 | 上海办公室装修,办公楼装修设计,办公空间设计,企业展厅设计_写艺装饰公司 | 重庆LED显示屏_显示屏安装公司_重庆LED显示屏批发-彩光科技公司 重庆钣金加工厂家首页-专业定做监控电视墙_操作台 | 纯水电导率测定仪-万用气体检测仪-低钠测定仪-米沃奇科技(北京)有限公司www.milwaukeeinst.cn 锂辉石检测仪器,水泥成分快速分析仪-湘潭宇科分析仪器有限公司 手术室净化装修-手术室净化工程公司-华锐手术室净化厂家 | 磁力反应釜,高压釜,实验室反应釜,高温高压反应釜-威海自控反应釜有限公司 | 淋巴细胞分离液_口腔医疗器材-精欣华医疗器械(无锡)有限公司 |