python教程—为什么p[:]被设计成在这两种情况下工作方式不同?-Python实用宝典

python教程—为什么p[:]被设计成在这两种情况下工作方式不同?

以上证实了p[:]在这两种情况下并不是同样有效的。考虑到在接下来的代码中,我希望直接使用p而不是p的副本,
    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]

我觉得

    del p[:]

是否与p[:]一致,它们都引用了原始列表

    q=p[:]

让(像我这样的新手)感到困惑,因为p[:]在这种情况下会产生一个新的列表!

我的新手期望是这样的

    q=p[:]

应该是一样的吗

    q=p

为什么创造者允许这种特殊的行为产生一个副本呢?

回答

del和作业的设计是一致的,只是它们的设计方式不是你所期望的那样。del从不删除对象,它删除名称/引用(对象删除只间接发生,删除对象的是refcount/垃圾收集器);类似地,赋值操作符从不复制对象,它总是创建/更新名称/引用。

del和赋值操作符采用引用规范(类似于C中的lvalue概念,尽管细节有所不同)。这个引用规范要么是一个变量名(纯标识符),要么是一个_setitem__键(方括号中的对象),要么是一个_setattr__名(点之后的标识符)。此lvalue不像表达式那样求值,因为这样做将使赋值或删除任何内容成为不可能。

考虑以下对称性:

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

    del p[:]

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

    q = p[:]

​Python实用宝典 (pythondict.com)
不只是一个宝典
欢迎关注公众号:Python实用宝典

本文由 Python实用宝典 作者:Python实用宝典 发表,其版权均为 Python实用宝典 所有,文章内容系作者个人观点,不代表 Python实用宝典 对观点赞同或支持。如需转载,请注明文章来源。
2

发表评论