>>>"helloworld"[::1]
'helloworld'
>>>"helloworld"[::-1]
'dlrowolleh'
根据语法str[start:end:step]
。
在两种情况下,默认为0。
在第一种情况下,字符串从索引值0打印。
但在第二种情况下,字符串从索引值-1打印。
我的问题是为什么在后一种情况下从-1打印字符串以及为什么会这样?
答案 0 :(得分:6)
根据the documentation(强调补充):
具有步骤k的从i到j的s的片被定义为具有索引x = i + n * k的项的序列,使得0 <= n <1。 (J-I)/ K。换句话说,索引是i,i + k,i + 2 * k,i + 3 * k等等,当到达j时停止(但是从不包括j)。如果i或j大于len(s),则使用len(s)。 如果i或j被省略或无,则它们变为“结束”值(其结束取决于k的符号)。注意,k不能为零。如果k为None,则将其视为1。
这意味着如果切片步幅为正,则ommited slice start是序列的开始,省略的切片end是序列的结束。如果切片步幅为负,则相反。如果您填写以下两个值中的一个,则可以看到此信息:
>>> '0123456'[:3]
'012'
>>> '0123456'[:3:-1]
'654'
>>> '0123456'[3:]
'3456'
>>> '0123456'[3::-1]
'3210'
想到这一点的一种方法是将序列可视化为循环,其中起点和终点是相同的点。省略切片的一端时,您只是指定使用此“两端点”作为端点,但不指定从那里开始的方向。这是一个步幅标志,告诉你走哪条路,这决定了你是否将“两端点”视为序列的开始或结束。
答案 1 :(得分:2)
扩展切片组件都默认为None(而不是0和sys.maxint
用于简单切片):
>>> class A:
... def __getitem__(self, s):
... return s
...
>>> A()[::-1]
slice(None, None, -1)
>>> A()[:]
slice(0, 9223372036854775807, None)
因此,没有自动推测切片应默认从零开始。
答案 2 :(得分:1)
可视化
记住切片如何工作的最好方法是将索引视为指向字符之间,第一个字符的左边缘编号为0.然后,n个字符的字符串的最后一个字符的右边缘具有索引n ,例如:
+---+---+---+---+---+
| H | e | l | l | o |
+---+---+---+---+---+
0 1 2 3 4 5
-5 -4 -3 -2 -1
指数可能是负数,从右侧开始计数。 但请注意,-0实际上与0相同,因此它不会从右侧算起!
In [105]: "helloworld"[-0]
Out[105]: 'h'
In [106]: "helloworld"[0]
Out[106]: 'h'
即。为什么反向索引从-1开始
In [107]: "helloworld"[-1]
Out[107]: 'd'
获取字符串的第二个最后一个索引,即[-2]
,即最后一个字符
需要使用否定步进,添加步骤以进入下一个索引
In [108]: "helloworld"[-1 + -1]
Out[108]: 'l'
答案 3 :(得分:0)
使用step = 1,您将获得原始字符串,毫不奇怪。
使用step = -1,python可能会实现一个特殊情况:反转顺序。
毕竟,切片[start:end]
,如[:]
返回整个切片,这是预期的行为。因此将其视为两阶段操作:获取切片(在您的情况下为完整副本),应用步进(在您的情况下反向)。
答案 4 :(得分:0)
在python中,字符串索引如下所示。
"H e l l o"
0 1 2 3 4
-4 -3 -2 -1 0
将使用的索引取决于您正在拍摄的切片的方向。因为您给出的步骤方向相反,所以它使用下面的索引。但是文档中没有说明这一点。
编辑:
我实际上是重新检查并且很有趣
str[::-1]
str[0::-1]
str[-1::-1]
all返回相同的值。所以我在原帖中所说的似乎是错的。它看起来更像是一种错误或语言中的特殊情况处理。
答案 5 :(得分:0)
您所看到的内容称为striding
:
>>> 'helloworld'[::1]
在
时返回所有元素>>> 'helloworld'[::2]
'hlool'
返回每个第2个元素。所以,现在尝试:
>>> 'helloworld'[::-2]
'drwle'
从结尾返回每2个元素。 因此,自然而言,最后的所有元素都是反向字符串:
>>> 'helloworld'[::-1]
'dlrowolleh'
答案 6 :(得分:0)
当字符串反转时,start不是隐式-1
是没有意义的。如果您尝试使用显式索引,那么当使用-1
作为步骤时,您将看到起始索引必须位于结束索引的右侧:
>>> "helloworld"[0:-1:-1]
''
>>> "helloworld"[-1:0:-1]
'dlrowolle'
就像切割正常方式时一样,范围包括起点而不包括终点,因此索引h
处的0
不是范围的一部分。 (AFAIK)切片符号的限制是不可能对整个字符串进行显式反转,因为这不起作用:
>>> "helloworld"[-1:-1:-1]
''
因此,切片和反转功能必须有一个特殊情况:
def slice_and_reverse(s, a, b):
"Return a slice of s from a to but not including b, reversed."
if a == 0:
return s[b - 1::-1]
else:
return s[b - 1:a - 1:-1]