我有一个清单说,sample_list = [1,2,3,4,5,6,7]。
现在,当我尝试访问时:
print(sample_list[-2:2])
Run Code Online (Sandbox Code Playgroud)
或者,
print(sample_list[-3:-7])
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,我都会得到一个空列表。
难道它不应该按照从左到右的约定至少打印[6,7]或分别打印吗?[5,6,7]
我知道,我在语义上做了错误的事情。
(尝试以从右到左的方向打印列表?)
我想了解空列表背后的逻辑。这里发生了什么?
如果要从右向左切片,则需要提供负号step: sample_list[-2:2:-1]。这也会颠倒值的顺序。
像切片这样的东西[-2:2]并不是没有意义的。如果你sample_list[-2:2]在一份长度为二的清单上这样做,你就会得到整个事情的副本。在长度为三的列表中,您将得到一个仅包含中间元素的切片。仅适用于长度为 4 或更大的列表,您会得到一个空切片。如果它们自动逆转,那么其中一些情况就会模棱两可。
编辑:让我尝试做出更全面的解释。
Python 的切片语法是通过slice对象实现的。即,L[start:stop:step]相当于L[slice(start, stop, step)]。(嗯,这就是它在 Python 3 中的工作方式。出于向后兼容性的原因,Python 2 也有一种较旧的方法,即 using__getslice__和__setslice__方法,但使用对象的较新方法slice也适用。)
当您获取切片、列表或元组时,您始终会获取从索引开始的元素start,一直到 之前的元素stop。该step参数描述了所采取的步骤的大小,2意味着每隔一个值,并且-1意味着相反的步骤。
另一种思考方式是切片L[start:stop:step]几乎等同于列表理解[L[i] for i in range(start, stop, step)]。差异仅在于当某些值为负数或未提供时会发生什么情况。
处理负值的规则很简单(与非切片索引相同)。对于start和stop,只需将序列的长度添加到任何负值即可。因此,对于正x和y,切片L[-x:-y]完全等于L[len(L)-x:len(L)-y]。负值step不会被转换。
与常规索引不同,切片不会因索引超出范围而引发异常。如果索引无效,您可能会得到空结果,或者只是比切片要求的值少。
并非切片的所有参数都是必需的。对象slice的构造函数None为未提供的任何参数分配默认值。这些Nones 的含义start和stop不同之处取决于 的符号step以及正在切片的列表的维度。
如果step是,None则始终将其视为好像是1。如果step是正数(或None),则start的值None将被视为是0,而stop的值None将被视为len(L)。如果step为负数,则start的值None被视为-1,stop的值None被视为-len(L)-1。
因此,回到你的问题,当你执行 slice 时sample_list[-2:2],会发生几件事:
首先,slice创建一个对象,就像您所做的那样slice(-2, 2)。该切片对象将具有stepof None,因为您没有提供第三个值。
接下来,slice被传递到列表并解释值。由于stepwas ,因此使用None默认值。1由于start是负数,因此将列表的长度添加到其中。
最后,结果就出来了。对于包含七个值的示例列表,您将得到相当于[sample_list[i] for i in range(5, 2, 1)]. 由于范围为空,因此切片也是空的。
根据您的需要,您可以通过几种不同的方式解决此问题。您可以保留它,您只会获得非常短的源列表的结果,其中len(L)-2小于2。或者,您可以交换前两个参数的顺序,并得到结果[3,4,5]。或者您可以添加负数step并从右到左切片,从而得到[6, 5, 4].
| 归档时间: |
|
| 查看次数: |
3283 次 |
| 最近记录: |