为什么 p[:] 的设计在这两种情况下的工作方式不同?

2024-02-27

p = [1,2,3]
print(p) # [1, 2, 3]

q=p[:]  # supposed to do a shallow copy
q[0]=11
print(q) #[11, 2, 3] 
print(p) #[1, 2, 3] 
# above confirms that q is not p, and is a distinct copy 

del p[:] # why is this not creating a copy and deleting that copy ?
print(p) # [] 

以上证实p[:]在这两种情况下的工作方式不同。不是吗?

考虑到在下面的代码中,我希望直接使用p而不是副本p,

p[0] = 111
p[1:3] = [222, 333]
print(p) # [111, 222, 333]

I feel

del p[:] 

和......一致p[:],全部引用原始列表 但

q=p[:] 

(对于像我这样的新手来说)令人困惑p[:]在这种情况下会产生一个新列表!

我的新手期望是

q=p[:]

应该是一样的

q=p

为什么创作者允许这种特殊行为产生副本?


del 和作业的设计是一致的,它们只是没有按照您期望的方式设计。 del 从不删除对象,它删除名称/引用(对象删除仅间接发生,是引用计数/垃圾收集器删除对象);类似地,赋值运算符从不复制对象,它总是创建/更新名称/引用。

del 和赋值运算符采用参考规范(类似于 C 中左值的概念,尽管细节有所不同)。该参考规范可以是变量名(普通标识符)、__setitem__键(方括号中的对象),或__setattr__名称(点后的标识符)。该左值不会像表达式一样进行计算,因为这样做将导致无法分配或删除任何内容。

考虑以下之间的对称性:

p[:] = [1, 2, 3]

and

del p[:]

在这两种情况下,p[:]工作原理相同,因为它们都被评估为左值。另一方面,在下面的代码中,p[:]是一个完全计算为对象的表达式:

q = p[:]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 p[:] 的设计在这两种情况下的工作方式不同? 的相关文章

随机推荐