切片操作实际上在python中返回什么

问题描述 投票:0回答:1

“所有切片操作都返回一个包含所请求元素的新列表”这是来自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)这表明确实返回了一个新列表。切片列表时真正发生了什么?

请指出我的无知。提前致谢。

python slice
1个回答
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() objectlist.__getitem__方法将其解释为对复制了匹配索引的新列表对象的请求。其他对象类型可以选择以不同方式解释切片对象。

请注意,还有第三个操作,del statement删除引用,包括切片。删除采用相同的target_list语法并要求删除切片指示的索引。

这三个操作在引擎盖下由object.__getitem__()(阅读),object.__setitem__()(写作)和object.__delitem__()(删除)钩子方法实现;每个操作的key参数是一个slice()对象,但只有__getitem__预计会返回任何东西。

© www.soinside.com 2019 - 2024. All rights reserved.