Understanding negative steps in list slicing
我试图理解以下行为,并欢迎任何参考(特别是官方文件)或评论。
让我们考虑一个列表:
1 | >>> x = [1,2,3,4,5,6] |
按预期工作
1 2 | >>> x[-1:-4:-1] [6, 5, 4] |
但我很惊讶以下内容是空的:
1 2 | >>> x[0:-4:-1] [] |
因此,我很惊讶以下内容并非空的
1 2 | >>> x[0:-len(x)-1:-1] > [1] |
尤其是考虑到这一点
1 2 | >>> x[0:-len(x):-1] [] |
而且
1 2 | >>> x[0:-len(x)-1] [] |
是空的。
事实是
1 2 3 4 | > x[-1:-4:-1] [6, 5, 4] > x[0:-4:-1] [] |
不应该让你吃惊!很明显,您可以向后分步骤从最后一个元素到最后一个元素的第四个,但不能从第一个元素分割列表。
在
1 | x[0:i:-1] |
1 | x[start:end:step] |
意思是,切片开始于
将
1 2 3 4 | > l[2::-1] [3, 2, 1] > l[0::-1] [1] |
我提到了参考实现(hattip指向匿名捐助者),发现从中理解行为是相当简单的。完整地说,imho这个行为是非指导性的,但是它仍然被很好地定义并与引用实现相匹配。
两个cpython文件是相关的,即描述list_subscript和pyslice_adjustindices的文件。在这种情况下,从列表中检索切片时,将调用列表下标。它称为pyslice_getindicex,而pyslice_又称为adjustindices。现在pyslice_adjustindices包含简单的if/then语句,用于调整索引。最后返回切片的长度。对我们来说,这些线条
1 2 3 4 5 6 | if (*stop < 0) { *stop += length; if (*stop < 0) { *stop = (step < 0) ? -1 : 0; } } |
具有特殊的相关性。调整后,
有趣的是注意到pyslice_adjustindices中有以下注释:
1 | /* this is harder to get right than you might think */ |
最后,请注意,在python文档中没有描述有关情况的处理。
1 | x[0:-4:-1] |
使用-1步从0转到2?