【发布时间】:2020-05-02 01:16:57
【问题描述】:
假设我们有一个列表a=[1,2,3],我需要将a 的元素复制到新列表b。
我们可以使用a=b,但a 和b 都指向同一个列表。因此,改变其中任何一个都会改变两个列表。
>>> a=b
>>> a
[1, 2, 3]
>>> b
[1, 2, 3]
>>> b.append(4)
>>> a,b
([1, 2, 3, 4], [1, 2, 3, 4])
>>> a.append(5)
>>> a,b
([1, 2, 3, 4, 5], [1, 2, 3, 4, 5])
>>> a is b
True
>>> id(a),id(b)
(2287659980360, 2287659980360)
为避免这种情况,我们可以使用b=a[:]。 a[:] 使用相同的 a 值创建一个不同的列表。现在,即使我改变了a,b 也不会受到影响,反之亦然。 b 和 b[:] 是两个不同的列表。
>>> b=a[:]
>>> a,b
([1, 2, 3, 4, 5], [1, 2, 3, 4, 5])
>>> a.append(6)
>>> a,b
([1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5])
>>> b.append(6)
>>> a,b
([1, 2, 3, 4, 5, 6], [1, 2, 3, 4, 5, 6])
>>> a is b
False
>>> id(a),id(b)
(2287659980360, 2287653308552)
现在,如果我这样做 b[:]=a 我的列表 b 正在发生变异。但是b[:] 是另一个列表,对吗? b 和 b[:] 都指向不同的列表,对吗?如果我错了纠正我。如果我变异b[:],为什么b 会被更改。我错过了什么?
>>> a=['a','b','c']
>>> b[:]=a
>>> a,b
(['a', 'b', 'c'], ['a', 'b', 'c'])
>>> id(b),id(b[:])
(2287653308552, 2287660267080)
>>> b is b[:]
False
【问题讨论】:
-
"Now, if I do b[:]=a my list b is being mutated."没有完全变异,而是被另一个列表覆盖,该列表重命名为b。 -
不是专家,但我假设当
b[:]被分配到时,它会修改列表b。但是,当在右侧调用b[:]时,它会返回一个包含b的每个元素的列表,该列表指向不同的位置# -
@SayandipDutta 绝对不是。
b引用的列表正在发生变化。 -
您混淆了两件事,切片和基于切片的分配。表达式
x[:]创建一个切片,隐式调用x.__getitem__,而语句x[:] = b是切片赋值,调用x.__setitem__ -
@juanpa.arrivillaga 感谢您抽出时间来解释并找到类似的问题。现在我明白了其中的区别。
标签: python python-3.x list slice