- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章通过源码分析Python中的切片赋值由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文主要介绍的关于Python切片赋值的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍:
昨天有同学问了我这么个问题
1
2
3
|
t
=
[
1
,
2
,
3
]
t[
1
:
1
]
=
[
7
]
# 感谢@一往直前 的疑问,之前写为 t[1:1] = 7了
print
t
# 输出 [1, 7, 2, 3]
|
这个问题之前还真没遇到过,有谁会对列表这么进行赋值吗?不过对于这个输出结果的原因确实值得去再了解下,毕竟之前也看过《Python源码分析》。(题外话:据说最近有大牛在写新的版本) 。
想着今天有空看看Python的源码,去了解下原理是什么.
注:我本地之前下载的是Python2.7.6的代码,直接看的这个.
在Objects/listobject.c中有一个 PyList_SetSlice 函数,是这么写的
1
2
3
4
5
6
7
8
9
|
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 ,那么再来看看这个函数的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
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;
/
*
the5fire注:
要赋值的长度n
*
/
n
=
PySequence_Fast_GET_SIZE(v_as_SF);
vitem
=
PySequence_Fast_ITEMS(v_as_SF);
}
if
(ilow <
0
)
ilow
=
0
;
else
if
(ilow > Py_SIZE(a))
ilow
=
Py_SIZE(a);
if
(ihigh < ilow)
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 <
0
) {
/
*
Delete
-
d items
*
/
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) <
0
)
goto Error;
item
=
a
-
>ob_item;
printf(
"关键点\n"
);
/
*
the5fire注:
把
list
对应切片后一位的值之后的所有内容向后移动所赋值的大小
按照上面的python代码这里就是
原理的t:
|
1
|
2
|
3
|
后移一位,因为
len
([
7
])
=
1
|
1
|空|
2
|
3
|把后两个移位
*
/
memmove(&item[ihigh
+
d], &item[ihigh],
(k
-
ihigh)
*
sizeof(PyObject
*
));
}
/
*
the5fire注:
赋值操作,即把[
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);
return
result;
#undef b
}
|
看了知乎,stackoverflow上的解答,发现源码还是最好的解释。上述关键位置已经加了注释,应该很好理解.
总结 。
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对我的支持.
原文链接:https://www.the5fire.com/python-slice-assignment-analyse-souce-code.html 。
最后此篇关于通过源码分析Python中的切片赋值的文章就讲到这里了,如果你想了解更多关于通过源码分析Python中的切片赋值的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
你能解释一下这个作业是如何完成的吗, var fe, f = document.forms[0], h; 哪个等于哪个。 最佳答案 以上等同于 var fe; var f = document.for
据我测试,这两种方法都有效,但我不知道哪一种最好,也不知道它们之间的区别,这就是我想知道的。 以下是两种方法: window.location = 'http://www.google.com'; w
我正在处理用字符串填充的 numpy 数组。我的目标是分配给第一个数组 a 的切片,值包含在较小尺寸的第二个数组 b 中。 我想到的实现如下: import numpy as np a = np.em
在我使用过的其他语言(如 Erlang 和 Python)中,如果我正在拆分字符串并且不关心其中一个字段,我可以使用下划线占位符。我在 Perl 中试过这个: (_,$id) = split('
我认为这似乎很简单,但我对调用、应用、绑定(bind)感到困惑。等等 我有一个事件监听器 red.addEventListener("click", function() { j = 0;
这个问题在这里已经有了答案: What is the python "with" statement designed for? (11 个答案) 关闭 7 年前。 使用有什么区别: iFile =
这个问题在这里已经有了答案: What is the python "with" statement designed for? (11 个答案) 关闭 7 年前。 使用有什么区别: iFile =
几周前我们开始写一篇关于 Haskell 的论文,刚刚接到我们的第一个任务。我知道 SO 不喜欢家庭作业问题,所以我不会问怎么做。相反,如果有人能将我推向正确的方向,我将不胜感激。鉴于它可能不是一个特
我正在尝试为我的函数的变量根分配一个值,但似乎不起作用。我不明白这个问题。 hw7.c:155:7:警告:赋值使指针来自整数而不进行强制转换[默认启用] root = 负载(&fp, 大小); 此代码
我昨天花了大约 5 个小时来完成这个工作,并使用这个网站的帮助让代码可以工作,但我认为我这样做的方式是一种作弊方式,我使用了 scanf 命令。无论如何,我想以正确的方式解决这个问题。多谢你们!哦,代
我需要一些帮助来解决问题。 我有这个文本文件: 我将文本内容输入到字符串二维数组中,并将其转换为整数二维数组。当我转换为 int 数组时,nan 被替换为零。现在,我继续查找二维数组中每行的最大值和最
假设我有一个只能移动的类型。我们停止现有的默认提供的构造函数,但 Rvalue 引用引入了一种新的“ flavor ”,我们可以将其用于签名的移动版本: class CantCopyMe { priv
假设我有两个简单的对象,我想创建第三个对象来连接它们的属性。这非常有效: (()=>{ const a1 = {a: 2, b: 3} const b1 = {a: 100, c: 5}
我想知道我是否可以稍后在这样的代码中为 VAR 赋值 var myView: UIView func createView() { myView = UIView() { let _view =
我遇到了一些 Javascript/HTML/CSS 代码的问题。我对创建网站还很陌生,所以请多多包涵。 我最终想做的是从 javascript 中提取一个动态值并使用它对一些 div(在容器中)进行
#include class Box{ public: int x; Box(){ x=0; std::cout No move construction thanks to RV
我发现在javascript中&=运算符是按位赋值: var test=true; test&=true; //here test is an int variable javascript中是否存在
请帮助完成赋值重载函数的执行。 这是指令: 赋值运算符 (=),它将源字符串复制到目标字符串中。请注意,目标的大小需要调整为与源相同。 加法 (+) 和赋值 (=) 运算符都需要能够进行级联运算。这意
我有一个名为 SortedArrayList 的自定义结构它根据比较器对其元素进行排序,我想防止使用 operator[] 进行分配. 示例: 数组列表.h template class Array
我是 python 的新手,我看到了这种为列表赋值的形式 color= ['red' if v == 0 else 'green' for v in y] 但是如果我尝试用 3 个数字来做,例如 co
我是一名优秀的程序员,十分优秀!