【发布时间】:2010-10-04 07:55:42
【问题描述】:
我是 Python 的新手,并且在我的书中遇到了以下示例,但没有很好地解释。这是我从解释器打印出来的:
>>> s = 'spam'
>>> s[:-1]
'spa'
为什么没有开始边界和'-1' 的切片会返回除最后一个元素之外的所有元素?调用s[0:-1] 在逻辑上与调用s[:-1] 相同吗?它们都返回相同的结果。但我不确定python到底在做什么。任何帮助将不胜感激。
【问题讨论】:
我是 Python 的新手,并且在我的书中遇到了以下示例,但没有很好地解释。这是我从解释器打印出来的:
>>> s = 'spam'
>>> s[:-1]
'spa'
为什么没有开始边界和'-1' 的切片会返回除最后一个元素之外的所有元素?调用s[0:-1] 在逻辑上与调用s[:-1] 相同吗?它们都返回相同的结果。但我不确定python到底在做什么。任何帮助将不胜感激。
【问题讨论】:
是的,调用s[0:-1] 与调用s[:-1] 完全相同。
在 python 中使用负数作为索引返回列表右侧的第 n 个元素(与通常的左侧相反)。
所以如果你有一个这样的列表:
myList = ['a', 'b', 'c', 'd', 'e']
print myList[-1] # prints 'e'
打印语句将打印“e”。
一旦你理解了这一点(你可能已经明白了,不完全清楚这是否是你感到困惑的事情之一),我们就可以开始讨论切片了。
我将假设您了解沿 myList[2:4] 行(将返回 ['c', 'd'])的切片的基础知识,并直接跳入其中一侧留空的切片符号。
正如您在帖子中所怀疑的那样,myList[:index] 与 myList[0:index] 完全相同。
这也适用于其他方式,顺便说一句...myList[index:] 与 myList[index:len(myList)] 相同,并将返回列表中所有元素的列表,从 index 开始直到结束(例如print myList[2:] 将打印['c', 'd', 'e'])。
作为第三个注释,你甚至可以在 no 索引的地方做print myList[:],这基本上会返回整个列表的副本(相当于myList[0:len(myList)],返回['a' , 'b', 'c', 'd', 'e'])。如果您认为 myList 会在某个时候发生变化,但您希望将其副本保持在当前状态,这可能会很有用。
如果您还没有这样做,我会发现只是在 Python 解释器中乱搞对理解这些事情有很大帮助。我推荐IPython。
【讨论】:
>>> l = ['abc', 'def', 'ghi', 'jkl', 'mno', 'pqr', 'stu', 'vwx', 'yz&']
# I want a string up to 'def' from 'vwx', all in between
# from 'vwx' so -2;to 'def' just before 'abc' so -9; backwards all so -1.
>>> l[-2:-9:-1]
['vwx', 'stu', 'pqr', 'mno', 'jkl', 'ghi', 'def']
# For the same 'vwx' 7 to 'def' just before 'abc' 0, backwards all -1
>>> l[7:0:-1]
['vwx', 'stu', 'pqr', 'mno', 'jkl', 'ghi', 'def']
请不要对列表无精打采。
这里的标志很重要;当然-向后;你知道的步幅的价值。 步幅是一个具有大小和方向的“向量”(低于 -1,全部向后)。
l = [0,1,2,3,4,5,6,7,8,9]
l[7:2:-1], l[-3:2:-1], [-3:-8:-1],l[7:-8:-1]
所有结果都是[7, 6, 5, 4, 3]。
【讨论】:
负索引从末尾开始计算,因此 s[:-1] 等价于 s[:len(s)-1] 并且 s[-1] 是最后一个元素。
【讨论】:
关键的一点是,python 索引应该被认为是指向列表中条目之间的空间的指针,而不是指向元素本身的指针。因此,0 指向开头,1 指向第一个和第二个之间,... 和 n 指向第 n 个和 (n+1)st 之间。
因此 l[1:2] 为您提供了一个仅包含元素 l[1] 的列表,因为它为您提供了两个指针之间的所有内容。
类似地,负索引指向元素之间,但这次从后面开始计数,所以 -1 指向最后一个元素和倒数第二个元素之间,所以 [0:-1] 指的是一个不包括最后一个。
作为语法糖,您可以从开头省略 0,或者实际上是结尾,因此 l[n:] 指的是从 l[n] 到结尾的所有内容(如果 n>=len(l) 则它返回空列表)。
【讨论】:
是的,调用s[0:-1] 在逻辑上与s[:-1] 相同,因为切片最好定义为:
[beginning_index:ending_index]
Python 允许您省略 0,因为这可以让您的代码更简洁。
【讨论】:
如果我们想从字符串的后端打印,我们可以使用负索引。索引从 -1 开始。
示例:s = 'hello world'
s[-11:-1] = '你好世界' s[-1:-11] = '' // 起始值应该更低(即,在这种情况下,-1 大于 -11)如果它更大,则不会打印任何内容。
【讨论】:
我将解决其他人遗漏的一点:
根据我们对切片的了解,我们如何解释这个负指数?
一般来说,当我们进行切片时,我们会谈论 [inclusive,exclusive] 边界。所以
A = [1,3,4,6]
A[1:3] # will give us 3-1 = 2 elements, index 1 and 2 => [3,4]
所以当我们在切片中有一个负索引时,A[1:-1],这意味着我们有A[1:len(A)-1] = A[1:3],这又给了我们索引 1 和 2,因此是[3,4]。
请注意,即使列表的长度为 4,它的最后一个索引也是 3,因此这个 -1 表示法在这里可以工作。另请注意,如果您有将负索引作为变量的代码,那么您需要手动检查 0,因为
A[:-0] == A[:0] == []
`
【讨论】: