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

时间:2017-12-25 11:35:27

标签: python python-3.x list variable-assignment slice

根据extended slices上的Python文档:

  

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

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

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

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

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

1 个答案:

答案 0 :(得分:4)

如果你试图想象如何

,这会更容易看到问题
a[::3] = [0, 1, 2]

可以使用4个项目列表:

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

我们试图取代每三个值,但我们的列表还不够长,所以如果我们继续前进,我们最终会得到一些奇怪的frankenstein列表,其中一些项目实际上并不存在。如果有人然后尝试访问a[5]并获得IndexError(即使a[6]正常工作),他们就会真的混淆。

虽然你可以通过将a[::2]扩展为a来从技术上解决问题,但为了保持一致性,Python禁止所有扩展切片分配,除非已经存在值的位置

常规切片总是有一个步幅,因此不会出现任何间隙,因此可以安全地允许分配。