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

Why is extended slice assignment less flexible than regular slice assignment?

根据 Python 关于 extended slices 的文档:

If you have a mutable sequence such as a list or an array you can assign to or delete an extended slice, but there are some differences between assignment to extended and regular slices. Assignment to a regular slice can be used to change the length of the sequence:

>>> a = range(3)
>>> a
[0, 1, 2]
>>> a[1:3] = [4, 5, 6]
>>> a
[0, 4, 5, 6]

Extended slices aren't this flexible. When assigning to an extended slice, the list on the right hand side of the statement must contain the same number of items as the slice it is replacing:

>>> 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

我不明白为什么 "ordinary" 切片方法有效,而 "extended" 切片方法无效。 "ordinary" 切片与 "extended" 切片有什么区别,为什么 "extended" 切片方法会失败?

如果你试着想象一下问题是如何发生的,就会更容易看出问题

a[::3] = [0, 1, 2]

适用于 4 项列表:

+---+---+---+---+   +   +---+
| a | b | c | d |       | ? |
+---+---+---+---+   +   +---+
  ^           ^           ^
+---+       +---+       +---+
| 0 |       | 1 |       | 2 |
+---+       +---+       +---+

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

虽然从技术上讲,您可以通过将 a 扩展一个来摆脱 a[::2] 的情况,但为了保持一致性,Python 禁止所有扩展的切片分配,除非已经有一个位置为了价值。

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