在python中使用字符串扩展切片

时间:2012-10-16 07:33:51

标签: python slice

>>>"helloworld"[::1]
'helloworld'

>>>"helloworld"[::-1]
'dlrowolleh'

根据语法str[start:end:step]。 在两种情况下,默认为0。 在第一种情况下,字符串从索引值0打印。 但在第二种情况下,字符串从索引值-1打印。

我的问题是为什么在后一种情况下从-1打印字符串以及为什么会这样?

7 个答案:

答案 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]