为什么 b[:]=a 会改变列表 b?

Ch3*_*teR 1 python list slice python-3.x

假设我们有一个列表a=[1,2,3],我需要将 的元素复制a到新列表b

我们可以做的a=b,但两者ab指向同一个列表。因此,改变它们中的任何一个都会改变两个列表。

>>> 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)
Run Code Online (Sandbox Code Playgroud)

为了避免这种情况,我们可以这样做b=a[:]a[:]创建一个具有相同值的不同列表a。现在,即使我 mutate ab也不会受到影响,反之亦然。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)
Run Code Online (Sandbox Code Playgroud)

现在,如果我这样做,b[:]=a我的清单b就会发生变异。但b[:]另一个清单对吗?双方bb[:]指向不同的名单吗?如果我错了纠正我。b如果我 mutate ,为什么会被改变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
Run Code Online (Sandbox Code Playgroud)

use*_*ica 7

切片在用作表达式或赋值目标时意味着不同的东西。

作为表达式,求值b[:]会生成一个新列表。但是,作为赋值目标,赋值给b[:]并不意味着“评估表达式b[:]然后赋值给结果列表”。无论如何,您不能在 Python 中分配对象。

作为分配目标,assigning tob[:]告诉现有列表将其内容替换为您分配给的任何元素的元素b[:]。这是由__setitem__方法处理的,例如b.__setitem__(slice(None, None), a). 不会生成新列表,b[:]也不会将其计算为表达式。

您可以在赋值语句的语言参考文档中看到这一点,在“如果目标是切片”下(尽管切片赋值的一些约束不像文档描述的那样严格;例如,文档说序列类型需要匹配,但对于大多数类型,它们不需要)。