python list assignment index_python-list-源码学习

# list_resize是一个通用方法static int

list_resize(PyListObject *self, Py_ssize_t newsize)

{

PyObject **items;

size_t new_allocated, num_allocated_bytes;

Py_ssize_t allocated = self->allocated;

/* Bypass realloc() when a previous overallocation is large enoughto accommodate the newsize. If the newsize falls lower than halfthe allocated size, then proceed with the realloc() to shrink the list.*/

# 这里说明,当新尺寸小于等于可容纳元素数量,同时大于等于可容纳数量的一半时 #,开始重新缩减列表尺寸大小,简单调整ob_size if (allocated >= newsize && newsize >= (allocated >> 1)) {

assert(self->ob_item != NULL || newsize == 0);

Py_SIZE(self) = newsize;

return 0;

}

/* This over-allocates proportional to the list size, making room* for additional growth. The over-allocation is mild, but is* enough to give linear-time amortized behavior over a long* sequence of appends() in the presence of a poorly-performing* system realloc().* The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...* Note: new_allocated won't overflow because the largest possible value* is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t.*/

new_allocated = (size_t)newsize + (newsize >> 3) + (newsize < 9 ? 3 : 6);

if (new_allocated > (size_t)PY_SSIZE_T_MAX / sizeof(PyObject *)) {

PyErr_NoMemory();

return -1;

}

if (newsize == 0)

new_allocated = 0;

num_allocated_bytes = new_allocated * sizeof(PyObject *);

items = (PyObject **)PyMem_Realloc(self->ob_item, num_allocated_bytes);

if (items == NULL) {

PyErr_NoMemory();

return -1;

}

self->ob_item = items;

Py_SIZE(self) = newsize;

self->allocated = new_allocated;

return 0;

}

# 这个插入动作确实导致了元素列表的内存发生变化static int

ins1(PyListObject *self, Py_ssize_t where, PyObject *v)

{

Py_ssize_t i, n = Py_SIZE(self);

PyObject **items;

if (v == NULL) {

PyErr_BadInternalCall();

return -1;

}

if (n == PY_SSIZE_T_MAX) {

PyErr_SetString(PyExc_OverflowError,

"cannot add more objects to list");

return -1;

}

# 重新分配 if (list_resize(self, n+1) < 0)

return -1;

if (where < 0) {

where += n;

if (where < 0)

where = 0;

}

if (where > n)

where = n;

items = self->ob_item;

for (i = n; --i >= where; )

items[i+1] = items[i];

Py_INCREF(v);

items[where] = v;

return 0;

}

PyList_Insert(PyObject *op, Py_ssize_t where, PyObject *newitem)

{

if (!PyList_Check(op)) {

PyErr_BadInternalCall();

return -1;

}

return ins1((PyListObject *)op, where, newitem);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中,当使用索引来给列表赋值时,如果索引超出了列表的范围,就会出现"list assignment index out of range"的错误。这个错误通常发生在尝试通过索引来修改列表中不存在的元素时。这个错误可以通过检查索引的范围是否正确来避免。另外,避免在遍历列表时对列表进行修改,因为这可能导致遍历错误。如果需要删除或修改列表中的元素,可以使用列表推导式或者创建一个新的列表来实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [解决:python中出现:list assignment index out of range](https://blog.csdn.net/gufenchen/article/details/100165861)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [python 的列表遍历删除实现代码](https://download.csdn.net/download/weixin_38652147/14863954)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [python报错:IndexError: list assignment index out of range](https://blog.csdn.net/frankyaixu/article/details/129233782)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值