a[len(a):] = [x]和a[len(a)] = [x]的区别是什么?

3
为什么a[len(a):] = [x]等同于a.append(x),但是a[len(a)] = [x]会导致“超出范围”的错误?
3个回答

4
根据 文档 (强调是我的):
如果目标是一个下标引用,且主表达式是可变序列对象(如列表),则必须使用下标引用一个普通整数。如果下标为负数,则需要将序列的长度加上它。结果必须是一个非负整数,小于序列的长度,并且要求序列将分配的对象分配给具有该索引的项。 如果索引超出范围,则会引发IndexError(赋值给下标化序列不能向列表添加新项)。
如果目标是一个切片:计算引用中的主表达式。 它应产生一个可变序列对象(例如列表)。被分配的对象应为相同类型的序列对象。 接下来,评估下限和上限表达式,只要它们存在; 默认值为零和序列的长度。 这些边界应该评估为(小)整数。 如果任一边界为负,则需要将序列的长度加上它。 结果的边界被裁剪为介于零和序列长度之间(含两端)。 最后,序列对象被要求使用分配的序列的项目替换切片。 切片的长度可以与分配的序列的长度不同,从而更改目标序列的长度,如果对象允许它。
因此,对于切片赋值可以更改列表的长度,但是对于索引(下标引用)赋值不能更改列表的长度。

3

这是语言所做的明确选择:对索引进行赋值需要这些索引存在。对切片进行赋值将根据需要扩展或收缩列表以适应新的大小。


2

Python 的切片(slicing)通常比使用数字进行索引更加“宽容”(这是设计上的考虑)。例如:

lst = []
lst[1:100]  # No exception here.

我认为切片赋值的情况只是这种“宽容性”的扩展。有趣的是,你甚至可以使用远超范围的索引:

a = []
a[100:101] = ['foo']

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接