为什么扩展切片分配不如常规切片分配灵活?

4 python list variable-assignment slice python-3.x

根据有关扩展切片的 Python 文档:

如果您有一个可变序列,例如列表或数组,您可以分配或删除扩展切片,但分配给扩展切片和常规切片之间存在一些差异。对常规切片的赋值可用于更改序列的长度:

>>> a = range(3)
>>> a
[0, 1, 2]
>>> a[1:3] = [4, 5, 6]
>>> a
[0, 4, 5, 6]
Run Code Online (Sandbox Code Playgroud)

扩展切片不是那么灵活。分配给扩展切片时,语句右侧的列表必须包含与其要替换的切片相同数量的项目:

>>> a = range(4)
>>> a
[0, 1, 2, 3]
>>> a[::2]
[0, 2]
>>> a[::2] = [0, -1]
>>> a
[0, 1, -1, 3]
>>> a[::2] = [0,1,2]
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ValueError: attempt to assign sequence of size 3 to extended slice of size 2
Run Code Online (Sandbox Code Playgroud)

我不明白为什么“普通”切片方法有效,但“扩展”切片方法不起作用。“普通”切片与“扩展”切片的区别是什么,为什么“扩展”切片方法会失败?

Zer*_*eus 7

如果你试着想象一下如何看问题就会容易一些

a[::3] = [0, 1, 2]
Run Code Online (Sandbox Code Playgroud)

将使用 4 项列表:

+---+---+---+---+   +   +---+
| a | b | c | d |       | ? |
+---+---+---+---+   +   +---+
  ^           ^           ^
+---+       +---+       +---+
| 0 |       | 1 |       | 2 |
+---+       +---+       +---+
Run Code Online (Sandbox Code Playgroud)

我们试图替换每三个值,但我们的列表不够长,所以如果我们继续进行,我们最终会得到某种奇怪的弗兰肯斯坦列表,其中一些项目实际上并不存在。如果有人随后尝试访问a[5]并获得IndexError(即使a[6]工作正常),他们会非常困惑。

尽管技术上可以a[::2]通过扩展a1来避免这种情况,但为了一致性,Python 禁止所有扩展的切片赋值,除非已经有一个值可以去的地方。

常规切片的步幅始终为 1,因此不会出现任何间隙,因此可以安全地允许分配。