提问人:mrwonderfulness 提问时间:8/19/2022 最后编辑:Rodrigo Rodriguesmrwonderfulness 更新时间:8/20/2022 访问量:146
Python 中奇怪的切片行为
Strange slicing behavior in Python
问:
我觉得这有点奇怪。谁能向我解释一下:为什么,如果我有这样的列表:
l = [1, 2, 3, 4, 5]
我做这个重新分配:
l[-1:0] = [99,]
然后它将 99 插入 5 的左侧,如下所示:
[1, 2, 3, 4, 99, 5]
我们必须赋值给一个可迭代对象,只赋值整数会给出一个错误,这可能是这里发生的事情的线索......我想?[99,]
99
答:
首先,您需要了解切片是如何完全工作的。可以有 3 个值:[start:end:step]
在代码中,使用 as 值将瞄准列表中的最后一个值,但由于设置了值,它也会尝试查找值列表。这就是为什么您必须使用列表来更改值的原因。l[-1:0]
-1
start
end
若要解决此问题,请将列表的最后一个值更改为 (假设这是预期结果)l[-1] = 99
99
评论
[99,]
不是元组。我不认为 OP 是询问如何更改列表的最终值。我认为他们要求澄清为什么他们会看到他们分享的行为。
当你用一个 Python 列表切片时,你最终会得到另一个列表。示例中新列表的开头是原始列表中最后一个元素的位置。仅仅因为您的示例中的值为 它并不意味着这只是一个空列表。它的值是一个空列表,但对的引用是现有列表中的切片列表。[start:end]
l[-1:0]
[]
l[-1:0]
所以在你的例子中
l = [1,2,3,4,5]
# ^ l[-1:0] starts here but the size is 0
将一个列表分配给另一个列表的切片位置时,您实际上是在执行列表连接。 这相当于你正在做的事情。
l=[1,2,3,4,5]
l[4:0] = [99] # concatenate a new list at the position of the final element in the original list
# A different way to look at it
l[0:4] + [99] + l[4:]
结果再次有效地将两个列表连接起来。更具体地说,您正在将新列表的元素插入到原始列表中的指定位置。使用文本整数(如 )将导致错误,因为您无法直接连接 int 和 list。然而,正如其他人所指出的,切片赋值可以使用任何可迭代的,因此工作原理相同。99
l[-1,0] = (99,)
评论
l[4:0] = (99,)
l[0:4] + (99,) + l[4:]
[]
type(l[-1:0])
list
type(range(0))
range
for i in range(0): print(i)
)
[]
l[-1:0]
根据官方文档:
在表中,s 是可变序列类型的实例,t 是任何可迭代对象,x 是满足 s 施加的任何类型和值限制的任意对象
注(1):t的长度必须与它所替换的切片相同。
因此,如果您这样做,则将位置 -1(这意味着比最后一个少一个)中的项目替换为值 99。l[-1] = 99
另一方面,如果你这样做,你把索引 -1 到 0 的元素(这意味着,在位置 -1 处的长度为 0 的切片),并用 [99,] 的元素替换它们(这就是为什么它必须是可迭代的),这实际上是一个语义插入。l[-1:0] = [99,]
评论
l[-1:0]
评论
[99,]
99
list
int