“所有切片操作都返回一个包含所请求元素的新列表” 这是来自python教程。
但如果是这种情况,那么为什么这段代码会这样:
>>> a = [11, 3, 1999]
>>> a[:] = [9, 78]
>>> a
[9, 78]
1)如果切片返回一个新列表,那么我为什么对新的绑定会影响原始绑定。这表明了什么?
但后来我也观察到了这一点:
>>> b = [4, 5, 6]
>>> b[:].append(5)
>>> b
[4, 5, 6]
>>> print(b)
[4, 5, 6]
2)这表明确实返回了一个新列表。切片列表时真正发生了什么?
请指出我的无知。提前谢谢。
答案 0 :(得分:4)
您将表达式与赋值混淆。获取值(读取)的处理方式与设置值(写入)不同。
分配(设置)重用语法来指定目标。在a[:] = ...
之类的作业中,a[:]
是作业发生的目标。在表达式中使用a[:]
会生成一个新列表。
换句话说:您有两种不同的语言语句,它们故意使用相同的语法。但它们仍然是截然不同的。
请参阅Assignment statements reference documentation:
assignment_stmt ::= (target_list "=")+ (starred_expression | yield_expression) target_list ::= target ("," target)* [","] target ::= identifier | "(" [target_list] ")" | "[" [target_list] "]" | attributeref | subscription | slicing | "*" target
[...]
- 如果目标是切片:评估参考中的主表达式。它应该产生一个可变序列对象(例如列表)。分配的对象应该是相同类型的序列对象。接下来,评估下限和上限表达式,只要它们存在;默认值为零和序列的长度。边界应该评估为整数。如果任一边界为负数,则将序列的长度添加到其中。生成的边界被裁剪为介于零和序列的长度之间(包括端点)。 最后,要求序列对象将切片替换为指定序列的项目。切片的长度可能与指定序列的长度不同,因此如果目标序列允许,则改变目标序列的长度。
(大胆强调我的)。
将其与表达式参考文档中的Slicings section进行比较;在表达式中切片会产生slice()
object,list.__getitem__
方法将其解释为对复制了匹配索引的新列表对象的请求。其他对象类型可以选择以不同方式解释切片对象。
请注意,第三个操作,del
statement到删除引用,包括切片。删除采用相同的target_list
语法,并要求删除切片指示的索引。
这三项操作全部由object.__getitem__()
(阅读),object.__setitem__()
(写作)和object.__delitem__()
(删除)钩子方法实现;每个操作的key
参数都是slice()
对象,但只有__getitem__
才能返回任何内容。