切片复制的目的不仅仅是为了保存一个内存地址吗?



我一直在读一篇关于Python陷阱的好文章。它讨论了在迭代列表的同时修改列表,并给出了以下示例:

>>> odd = lambda x : bool(x % 2)
>>> numbers = [n for n in range(10)]
>>> numbers[:] = [n for n in numbers if not odd(n)]
>>> numbers
[0, 2, 4, 6, 8]

在第三行,使用[:]切片表示法覆盖number变量,因此值id(numbers)不会改变。

我想知道除了节省额外的内存分配和相关的清理之外,这样做还有什么目的吗?您是否倾向于在日常代码中这样做,或者在正常情况下它被认为是过度优化?

任何其他对同一列表的引用也被更改。

如果将列表传递给函数,则该函数有一个绑定到相同列表对象的本地名称。重新绑定名称不会让您反映函数外部的更改,切片赋值会更改原始列表:

>>> def rebinds(lst):
...     lst = ['foo', 'bar', 'baz']
... 
>>> def slice_assigns(lst):
...     lst[:] = ['foo', 'bar', 'baz']
... 
>>> somelist = [42, 81]
>>> rebinds(somelist)
>>> somelist
[42, 81]
>>> slice_assigns(somelist)
>>> somelist
['foo', 'bar', 'baz']

您可以直接返回新对象并重新绑定全局对象,但是您可以直接更改列表内容,使更改对任何已经具有引用的代码可见,这是有好处的。