问题 从切片分配到vs.


阅读时 profile.py python标准库我遇到了赋值语句 sys.argv[:] = args,用于修改 sys.argv 使程序被分析查看正确的命令行参数。我明白这不同于 sys.argv = args[:] 在实际操作中,但是 有效 他们看起来和我一样。是否有人想要使用一个而不是另一个?并且是 a[:] = b 一个常见的蟒蛇成语?

更新:在这种特定情况下,为什么选择一个而不是另一个呢? (来源可以在 main 的功能 profile.py


3325
2017-10-17 03:10


起源



答案:


不同的是,当你使用时 a[:] = b 这意味着你将覆盖任何已经存在的东西 a。如果你有其他的参考 a 它也会改变,因为它不断引用相同的位置。

另一方面, a = b[:] 创建一个新引用并复制所有值 b 这个新的参考。因此,对旧数据的现有引用将继续指向旧数据。

考虑这个例子:

>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> c = a # c is a reference to the list in a
>>> c
[1, 2, 3]
>>> 
>>> a[:] = b
>>> a # a will have a copy of the list in b
[4, 5, 6] 
>>> c # and c will keep having the same value as a
[4, 5, 6]
>>>
>>> b = [7, 8, 9]
>>> a = b[:]
>>> a # a has the new value
[7, 8, 9]
>>> c # c keeps having the old value
[4, 5, 6]

9
2017-10-17 03:17



谢谢,我意识到如果有其他参考,这会有所不同 a - Tony Beta Lambda
举个例子可能会有所帮助。如果 x = [1, 2, 3],和 a = x (所以他们引用相同的列表),做 a = b[:] 取代了 参考 在 a 与副本 b; x 没有改变。另一方面, a[:] = b 取代了 内容 的 a (其引用不变)带有值 b, 意思是 x 也被修改;参考联系从未被打破过。 - ShadowRanger
我编辑了添加更多细节。但是一个例子应该是一件好事。我会加上它。 - Hugo Sadok
@TonyBetaLambda这个例子让它更清晰吗?还有其他一些你需要了解的吗? - Hugo Sadok
重新分配 sys.path 这种方式大多没有意义,但如果你需要重新分配a的内容,这个习惯用法很有用 list 作为参数传递给函数(修改调用者的副本)。只要 a[:] = b 将改变呼叫者(在哪里 a 是一个函数论证)。 - ShadowRanger


答案:


不同的是,当你使用时 a[:] = b 这意味着你将覆盖任何已经存在的东西 a。如果你有其他的参考 a 它也会改变,因为它不断引用相同的位置。

另一方面, a = b[:] 创建一个新引用并复制所有值 b 这个新的参考。因此,对旧数据的现有引用将继续指向旧数据。

考虑这个例子:

>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> c = a # c is a reference to the list in a
>>> c
[1, 2, 3]
>>> 
>>> a[:] = b
>>> a # a will have a copy of the list in b
[4, 5, 6] 
>>> c # and c will keep having the same value as a
[4, 5, 6]
>>>
>>> b = [7, 8, 9]
>>> a = b[:]
>>> a # a has the new value
[7, 8, 9]
>>> c # c keeps having the old value
[4, 5, 6]

9
2017-10-17 03:17



谢谢,我意识到如果有其他参考,这会有所不同 a - Tony Beta Lambda
举个例子可能会有所帮助。如果 x = [1, 2, 3],和 a = x (所以他们引用相同的列表),做 a = b[:] 取代了 参考 在 a 与副本 b; x 没有改变。另一方面, a[:] = b 取代了 内容 的 a (其引用不变)带有值 b, 意思是 x 也被修改;参考联系从未被打破过。 - ShadowRanger
我编辑了添加更多细节。但是一个例子应该是一件好事。我会加上它。 - Hugo Sadok
@TonyBetaLambda这个例子让它更清晰吗?还有其他一些你需要了解的吗? - Hugo Sadok
重新分配 sys.path 这种方式大多没有意义,但如果你需要重新分配a的内容,这个习惯用法很有用 list 作为参数传递给函数(修改调用者的副本)。只要 a[:] = b 将改变呼叫者(在哪里 a 是一个函数论证)。 - ShadowRanger