为啥我不能将任意迭代分配给步长为 -1 的扩展切片?

Posted

技术标签:

【中文标题】为啥我不能将任意迭代分配给步长为 -1 的扩展切片?【英文标题】:Why can't I assign an arbitrary iterable to an extended slice whose step is -1?为什么我不能将任意迭代分配给步长为 -1 的扩展切片? 【发布时间】:2012-06-13 09:12:22 【问题描述】:
Python 3.2.3 (default, Apr 11 2012, 07:15:24) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> u = [4, 5, 6, 7, 8, 9]
>>> u[1::1] = [3, 2, 1, 0]
>>> u
[4, 3, 2, 1, 0]
>>> u[9:0:-1] = [8, 7, 6, 5]
>>> u
[4, 5, 6, 7, 8]
>>> u[9:0:-1] = [16, 12, 8]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: attempt to assign sequence of size 3 to extended slice of size 4
>>> u
[4, 5, 6, 7, 8]
>>>

预期行为:最终赋值语句没有抛出异常; u 应该在最后一行打印为 [4, 8, 12, 16]

我可以分配一个步长为 1 的扩展切片,即使我分配的迭代是“错误的长度”。那为什么我不能分配给步长为 -1 的扩展切片并让它以明显的方式工作?

【问题讨论】:

【参考方案1】:

我认为创建一个步长为 1 的扩展切片实际上就像一个常规切片而不是扩展切片。

扩展切片不允许您更改序列的长度,如 here 所述

如果您有一个可变序列,例如列表或数组,您可以分配或删除扩展切片,但分配给扩展切片和常规切片之间存在一些差异。分配给常规切片可用于更改序列的长度。 扩展切片没有这么灵活。分配给扩展切片时,语句右侧的列表必须包含与其要替换的切片相同数量的项目。

至于为什么会这样,我只能猜测是因为没有明显行为的情况。举个例子:

u = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
u[0:8:3] = [ 10, 11 ]

您希望它如何工作?我想你可以用 10 和 11 替换 1 和 4,但是 7 呢?你留下吗?删除它?删除 7 之后的整个序列的其余部分?可能只有我一个人,不过这个案子好像不太清楚。我认为这就是为什么扩展切片不允许这种行为。

【讨论】:

有道理。尽管如此,OP 是正确的,对于 -1 的步长,预期的行为非常清楚,因此将这种特殊情况设置为 1 的步长可能会很好...... @weronika 同意,但请告诉 python 开发人员 ;)

以上是关于为啥我不能将任意迭代分配给步长为 -1 的扩展切片?的主要内容,如果未能解决你的问题,请参考以下文章

为啥数组不能分配给Iterable?

C++:为啥我不能将一对迭代器传递给 regex_search?

为啥我不能将 string::back 分配给字符串?

为啥我不能将具有用户定义参数的方法分配给 c# 中的按钮?

为啥我不能将 UIView 分配给 self.view?

为啥我不能将从 Firestore 获取的值分配给 Swift 中的数组?