a[:] = b 和 a = b[:] 之间的区别? (Python)
我被要求进行编码测试,但不知道答案。有人有什么想法吗?
I was asked this for a coding test and didn't know the answer. Anyone have any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在这两种情况下,最终列表
a
都是列表b
的副本。但用于实现这一目标的方法已经改变。a[:] = b
修改列表a
,使其具有与b
相同的元素a = b[:]< /code> 生成一个新列表,它是
b
的副本并替换列表a
区别在于我们是修改了现有列表还是创建了新列表。
要查看差异:
所有三个列表都会打印出相同的结果。 C 和 a 共享同一个对象,因此当
a
被修改时,c
也被修改,现在 c 不会打印出与 a 相同的内容。赋值后,
a
和c
不共享同一个对象。从速度上来说,
a[:] = b
可能比a = b[:]
快一点。第一种形式不必创建新的列表对象,它只需修改现有列表即可。其中很大一部分是它可以重用列表已经拥有的内存,而不是分配新的内存。In both cases you end up the list
a
being a copy of the listb
. But the method used to accomplish this has changed.a[:] = b
modifies the lista
so that it has the same elements asb
a = b[:]
produces a new list which is a copy ofb
and replaces the lista
The difference is whether we've modified an existing list or created a new one.
To see the difference:
All three lists will print out the same. C and a share the same object, so when
a
was modified so wasc
Now c will not print out the same as a. After the assignment,
a
andc
did not share the same object.Speedwise,
a[:] = b
is probably a little faster thana = b[:]
. The first form doesn't have to create a new list object, it can merely modify the existing list. A big part of this is that it can reuse the memory already owned by the list rather then allocating new memory.[:]
是切片运算符。当它位于左侧时,它会覆盖列表的内容而不创建新的引用。
当它位于右侧时,它会创建具有相同内容的列表的副本。
[:]
is the slice operator.When it's on the left side, it overwrites the contents of the list without creating a new reference.
When it's on the right side, it creates a copy of the list with the same contents.
a = b[:]
调用__getslice__
或__getitem__
上b
并将结果分配给a
。几乎在所有情况下(例如列表、元组和其他序列类型),这都会生成序列的浅表副本;我不知道有哪个类不实现该行为,但您可以有一个用户定义的类型来执行不同的操作。之前引用a
旧值的任何其他对象将继续引用该旧值。另一方面,
a[:] = b
调用__setslice__
或__setitem__
将a
的元素子集替换为序列b
的元素子集。在这种情况下,如果a
的序列类型表现良好,这将替换整个a
,因为范围:
没有端点表示整个序列。这里的区别在于,不可变类型(例如元组)不允许您执行 __setslice__ (例如,通过抛出TypeError
异常)。之前引用a
的任何其他对象也将被更新,因为底层对象正在被修改。对于诸如
list
之类的可变类型,a = b[:]
的结果将与a[:] = b
相同,因为a
将是b
的浅拷贝;对于不可变类型(例如元组),a[:] = b 无效。对于行为不良的用户定义类型,所有的赌注都失败了。对于以a
引用同一对象的其他对象,发生的情况也存在差异 - 对于a = b[:]
,它们引用原始值 (< code>a),但使用a[:] = b
时,它们引用修改后的对象(b
的浅拷贝)。a = b[:]
calls either__getslice__
or__getitem__
onb
and assigns the result toa
. In nearly all cases (e.g. lists, tuples, and other sequence types), this makes a shallow copy of the sequence; I don't know of any classes that don't implement that behavior, but you could have a user-defined type that did something different. Any other objects that previously referred to the old value ofa
will continue to refer to that old value.a[:] = b
, on the other hand, calls__setslice__
or__setitem__
to replace a subset of the elements ofa
with those of the sequenceb
. In this case, if the sequence type ofa
is well-behaved, this will replace the entirety ofa
, since the range:
without endpoints indicates the entire sequence. The difference here is that immutable types, such as tuples, will not allow you to perform__setslice__
(e.g. by throwing aTypeError
exception). Any other objects that previously referred toa
will also be updated, since the underlying object is being modified.For mutable types such as
list
, the result ofa = b[:]
will be identical toa[:] = b
, in thata
will be a shallow copy ofb
; for immutable types such astuple
,a[:] = b
is invalid. For badly-behaved user-defined types, all bets are off. There's also a difference in what happens to other objects that referred to the same object asa
-- witha = b[:]
, they refer to the original value (a
), but witha[:] = b
, they refer to the modified object (shallow copy ofb
).