有这么个问题::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中对切片赋值原理分析相关推荐

  1. python列表方法语句_Python中列表和元组的相关语句和方法讲解

    列表(list): 首先,列表属于序列,那么序列类型可用如下内建函数-- list(iter):把可迭代对象转换为列表. str(obj):把obj对象转换为字符串,即用字符串来表示这个对象. tup ...

  2. python列表对象相同_Python中的学习列表对象,List

    List(列表) 是 Python 中使用最频繁的数据类型. 列表可以完成大多数集合类的数据结构实现.列表中元素的类型可以不相同,它支持数字,字符串甚至可以包含列表(所谓嵌套). 列表是写在方括号 [ ...

  3. python列表的嵌套_Python中关于列表嵌套列表的处理

    在处理列表的时候我们经常会遇到列表中嵌套列表的结构,如果我们要把所有元素放入一个新列表,或者要计算所有元素的个数的话应该怎么做呢? 第一个例子 对于上图中的这样一组数据,如果我们要知道这个CSV文件中 ...

  4. python定义数组并赋值_python中的数组赋值与拷贝的区别详解

    具体的注解我已经写在了程序里面:通俗的解释了python里面的浅拷贝与深拷贝的不同,请看程序. # -*- coding: utf-8 -*- import numpy as np import co ...

  5. python默认参数举例_Python中的默认参数实例分析

    本文研究的主要是Python中的默认参数的相关内容,具体如下. 熟悉C++语言的可以知道,C++语言中的默认参数是写在函数声明中的,为语法糖,与函数的调用无关,是在函数调用的时候由编译器补齐参数然后进 ...

  6. python列表取出元素_python中的列表,添加元素,获取元素,删除元素,列表分片,常用操作符...

    一. 创建列表,分为创建普通列表,混合列表,和空列表.其中混合列表是指string,int, float等都可以写在同一个列表里,空列表是指列表可以为空 二. 在列表添加成员方法 1. append( ...

  7. python列表方法图解_python中list(列表)的使用方法总结(图文)

    本篇文章给大家带来的内容是关于python中list(列表)的使用方法总结(图文),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 1.list(列表)是一种有序的集合,可以随时添加. ...

  8. python列表大小限制_Python中列表的项数有限制吗?

    Python中列表的项数有限制吗? 关注:172  答案:1  mip版 解决时间 2021-01-13 18:03 已解决 2021-01-12 21:29 我在尝试生成一个900个项,每个项是包含 ...

  9. python列表数据排序_Python中,如何将列表中数据排序给列表排序?

    在程序中使用字典进行数据信息統计时由于字典是无序的所以打印字典时内容也是无序的.因此为了使统计得到的结果更方便查看需要进行排序.Python中字典的排序分为按"键"排序和按&quo ...

最新文章

  1. Linux 文件的权限
  2. (填坑:SQL打印两次)mybatisplus+p6spy 日志打印
  3. tf.lookup.StaticHashTable 用法
  4. [转载]关于申请国外博后的一点经验和想法
  5. 2018 青岛网络赛C题Halting Problem
  6. [LeetCode] Valid Anagram - 字符串排序比较系列
  7. 如何在SAP Kyma的控制台里扩展新的UI
  8. 重装系统win10提示磁盘布局不受UEFI固件支持怎么办
  9. DevExpress GridControl双击获取行内容
  10. 我的开发环境配置经验
  11. 锅打灰太狼/打地鼠项目
  12. 服务器文件mdf,升级 .mdf 文件 - Visual Studio (Windows) | Microsoft Docs
  13. 混沌matlab仿真
  14. Latex排版,表格标题总是出现在下方的解决方案
  15. bzoj1050 [HAOI2006]旅行comf(并查集)
  16. CF1463-C. Busy Robot
  17. Installation Installing SDKMAN
  18. 玩转NVIDIA Jetson AGX Xavier--- 中文用户手册
  19. Pipeline 基础步骤
  20. 理论总结-三次样条插值

热门文章

  1. LeetCode 735. 行星碰撞(栈)
  2. LeetCode 547. 朋友圈(图的遍历BFS DFS)
  3. LeetCode 938. 二叉搜索树的范围和(二叉树遍历+搜索剪枝)
  4. LeetCode 102. 二叉树的层次遍历(BFS)
  5. php判断全是中文正则,php判断是否为中文正则表达式大全
  6. linux webservice端口号,解决在Linux环境下访问webservice发送中文乱码问题的方案
  7. python中的进程, 线程
  8. 包概念与__init__注意事项
  9. Maven详解及实例
  10. R语言第八讲 评估模型之交叉验证法分析案例