a[start:stop] # items start through stop-1a[start:] # items start through the rest of the arraya[:stop] # items from the beginning through stop-1a[:] # a copy of the whole array
还有step值,可以与上述任何值一起使用:
a[start:stop:step] # start through not past stop, by step
a[-1] # last item in the arraya[-2:] # last two items in the arraya[:-2] # everything except the last two items
类似地,step可以是负数:
a[::-1] # all items in the array, reverseda[1::-1] # the first two items, reverseda[:-3:-1] # the last two items, reverseda[-3::-1] # everything except the last two items, reversed
+---+---+---+---+---+---+| P | y | t | h | o | n |+---+---+---+---+---+---+Slice position: 0 1 2 3 4 5 6Index position: 0 1 2 3 4 5
>>> p = ['P','y','t','h','o','n']# Why the two sets of numbers:# indexing gives items, not lists>>> p[0]'P'>>> p[5]'n'
# Slicing gives lists>>> p[0:1]['P']>>> p[0:2]['P','y']
一种启发式方法是,对于从零到n的切片,认为:“零是开头,从开头开始,在列表中取n个项目”。
>>> p[5] # the last of six items, indexed from zero'n'>>> p[0:5] # does NOT include the last item!['P','y','t','h','o']>>> p[0:6] # not p[0:5]!!!['P','y','t','h','o','n']
>>> p[0:4] # Start at the beginning and count out 4 items['P','y','t','h']>>> p[1:4] # Take one item off the front['y','t','h']>>> p[2:4] # Take two items off the front['t','h']# etc.
切片赋值的第一条规则是,由于切片返回是一个列表,切片赋值需要是一个列表(或其他可迭代的):
>>> p[2:3]['t']>>> p[2:3] = ['T']>>> p['P','y','T','h','o','n']>>> p[2:3] = 't'Traceback (most recent call last):File "<stdin>", line 1, in <module>TypeError: can only assign an iterable
>>> p = ['P','y','t','h','o','n']>>> p[0:4]['P','y','t','h']>>> p[1:4]['y','t','h']>>> p[2:4]['t','h']>>> p[3:4]['h']>>> p[4:4][]
然后一旦你看到了,对空切片的切片赋值也有意义:
>>> p = ['P','y','t','h','o','n']>>> p[2:4] = ['x','y'] # Assigned list is same length as slice>>> p['P','y','x','y','o','n'] # Result is same length>>> p = ['P','y','t','h','o','n']>>> p[3:4] = ['x','y'] # Assigned list is longer than slice>>> p['P','y','t','x','y','o','n'] # The result is longer>>> p = ['P','y','t','h','o','n']>>> p[4:4] = ['x','y']>>> p['P','y','t','h','x','y','o','n'] # The result is longer still
Python indexes and slices for a six-element list.Indexes enumerate the elements, slices enumerate the spaces between the elements.
Index from rear: -6 -5 -4 -3 -2 -1 a=[0,1,2,3,4,5] a[1:]==[1,2,3,4,5]Index from front: 0 1 2 3 4 5 len(a)==6 a[:5]==[0,1,2,3,4]+---+---+---+---+---+---+ a[0]==0 a[:-2]==[0,1,2,3]| a | b | c | d | e | f | a[5]==5 a[1:2]==[1]+---+---+---+---+---+---+ a[-1]==5 a[1:-1]==[1,2,3,4]Slice from front: : 1 2 3 4 5 : a[-2]==4Slice from rear: : -5 -4 -3 -2 -1 :b=a[:]b==[0,1,2,3,4,5] (shallow copy of a)
[a:b:c]
len = length of string, tuple or list
c -- default is +1. The sign of c indicates forward or backward, absolute value of c indicates steps. Default is forward with step size 1. Positive means forward, negative means backward.
a -- When c is positive or blank, default is 0. When c is negative, default is -1.
b -- When c is positive or blank, default is len. When c is negative, default is -(len+1).
了解索引分配非常重要。
In forward direction, starts at 0 and ends at len-1
In backward direction, starts at -1 and ends at -len
>>> l1[2, 3, 4]
>>> l1[:][2, 3, 4]
>>> l1[::-1] # a default is -1 , b default is -(len+1)[4, 3, 2]
>>> l1[:-4:-1] # a default is -1[4, 3, 2]
>>> l1[:-3:-1] # a default is -1[4, 3]
>>> l1[::] # c default is +1, so a default is 0, b default is len[2, 3, 4]
>>> l1[::-1] # c is -1 , so a default is -1 and b default is -(len+1)[4, 3, 2]
>>> l1[-100:-200:-1] # Interesting[]
>>> l1[-1:-200:-1] # Interesting[4, 3, 2]
>>> l1[-1:-1:1][]
>>> l1[-1:5:1] # Interesting[4]
>>> l1[1:-7:1][]
>>> l1[1:-7:-1] # Interesting[3, 2]
>>> l1[:-2:-2] # a default is -1, stop(b) at -2 , step(c) by 2 in reverse direction[4]
Index:------------>0 1 2 3 4+---+---+---+---+---+| a | b | c | d | e |+---+---+---+---+---+0 -4 -3 -2 -1<------------
Slice:<---------------||--------------->: 1 2 3 4 :+---+---+---+---+---+| a | b | c | d | e |+---+---+---+---+---+: -4 -3 -2 -1 :|---------------><---------------|
In [122]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']
In [123]: alphaOut[123]: ['a', 'b', 'c', 'd', 'e', 'f']
In [124]: alpha[0]Out[124]: 'a'
In [127]: alpha[0] = 'A'
In [128]: alphaOut[128]: ['A', 'b', 'c', 'd', 'e', 'f']
In [129]: alpha[0,1]---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-129-c7eb16585371> in <module>()----> 1 alpha[0,1]
TypeError: list indices must be integers, not tuple
s[-5:] # Start at the 5th index from the end of array,# thus returning the last 5 elements.s[:-5] # Start at index 0, and end until the 5th index from end of array,# thus returning s[0:len(s)-5].
s[::-1] # Reversed slices[len(s)::-1] # The same as above, reversed slices[0:len(s):-1] # Empty list
超出范围误差?
惊喜:当索引超出范围时,切片不会引发IndexError!
如果索引超出范围,Python会根据情况尽量将索引设置为0或len(s)。例如:
s[:len(s)+5] # The same as s[:len(s)]s[-len(s)-5::] # The same as s[0:]s[len(s)+5::-1] # The same as s[len(s)::-1], and the same as s[::-1]
3.实例
让我们用例子来结束这个答案,解释我们讨论的所有内容:
# Create our array for demonstrationIn [1]: s = [i for i in range(10)]
In [2]: sOut[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [3]: s[2:] # From index 2 to last indexOut[3]: [2, 3, 4, 5, 6, 7, 8, 9]
In [4]: s[:8] # From index 0 up to index 8Out[4]: [0, 1, 2, 3, 4, 5, 6, 7]
In [5]: s[4:7] # From index 4 (included) up to index 7(excluded)Out[5]: [4, 5, 6]
In [6]: s[:-2] # Up to second last index (negative index)Out[6]: [0, 1, 2, 3, 4, 5, 6, 7]
In [7]: s[-2:] # From second last index (negative index)Out[7]: [8, 9]
In [8]: s[::-1] # From last to first in reverse order (negative step)Out[8]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
In [9]: s[::-2] # All odd numbers in reversed orderOut[9]: [9, 7, 5, 3, 1]
In [11]: s[-2::-2] # All even numbers in reversed orderOut[11]: [8, 6, 4, 2, 0]
In [12]: s[3:15] # End is out of range, and Python will set it to len(s).Out[12]: [3, 4, 5, 6, 7, 8, 9]
In [14]: s[5:1] # Start > end; return empty listOut[14]: []
In [15]: s[11] # Access index 11 (greater than len(s)) will raise an IndexError---------------------------------------------------------------------------IndexError Traceback (most recent call last)<ipython-input-15-79ffc22473a3> in <module>()----> 1 s[11]
IndexError: list index out of range
+---+---+---+---+---+| H | e | l | p | A |+---+---+---+---+---+0 1 2 3 4 5-5 -4 -3 -2 -1
str="Name string"
切片示例:[start: end: Step]
str[start:end] # Items start through end-1str[start:] # Items start through the rest of the arraystr[:end] # Items from the beginning through end-1str[:] # A copy of the whole array
下面是示例用法:
print str[0] = Nprint str[0:2] = Naprint str[0:7] = Name stprint str[0:7:2] = Nm tprint str[0:-1:2] = Nm ti
In [1]: l = list(range(10))
In [2]: l[:5] # First five elementsOut[2]: [0, 1, 2, 3, 4]
In [3]: l[-5:] # Last five elementsOut[3]: [5, 6, 7, 8, 9]
从开始切片时,可以省略零索引,切片到最后时,可以省略最终索引,因为它是多余的,所以不要冗长:
In [5]: l[:3] == l[0:3]Out[5]: True
In [6]: l[7:] == l[7:len(l)]Out[6]: True
负整数在相对于集合末尾进行偏移时很有用:
In [7]: l[:-1] # Include all elements but the last oneOut[7]: [0, 1, 2, 3, 4, 5, 6, 7, 8]
In [8]: l[-3:] # Take the last three elementsOut[8]: [7, 8, 9]
可以提供切片时超出边界的索引,例如:
In [9]: l[:20] # 20 is out of index bounds, and l[20] will raise an IndexError exceptionOut[9]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [11]: l[-20:] # -20 is out of index bounds, and l[-20] will raise an IndexError exceptionOut[11]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [16]: l[2:6] = list('abc') # Assigning fewer elements than the ones contained in the sliced collection l[2:6]
In [17]: lOut[17]: [0, 1, 'a', 'b', 'c', 6, 7, 8, 9]
In [18]: l[2:5] = list('hello') # Assigning more elements than the ones contained in the sliced collection l [2:5]
In [19]: lOut[19]: [0, 1, 'h', 'e', 'l', 'l', 'o', 6, 7, 8, 9]
如果省略开始和结束索引,您将创建集合的副本:
In [14]: l_copy = l[:]
In [15]: l == l_copy and l is not l_copyOut[15]: True
如果在执行赋值操作时省略开始索引和结束索引,则集合的整个内容将被引用内容的副本替换:
In [20]: l[:] = list('hello...')
In [21]: lOut[21]: ['h', 'e', 'l', 'l', 'o', '.', '.', '.']
In [22]: l = list(range(10))
In [23]: l[::2] # Take the elements which indexes are evenOut[23]: [0, 2, 4, 6, 8]
In [24]: l[1::2] # Take the elements which indexes are oddOut[24]: [1, 3, 5, 7, 9]
In [29]: l = l[::2] # This step is for striding
In [30]: lOut[30]: [0, 2, 4, 6, 8]
In [31]: l = l[1:-1] # This step is for slicing
In [32]: lOut[32]: [2, 4, 6]
def slice(list, start = None, end = None, step = 1):# Take care of missing start/end parametersstart = 0 if start is None else startend = len(list) if end is None else end
# Take care of negative start/end parametersstart = len(list) + start if start < 0 else startend = len(list) + end if end < 0 else end
# Now just execute a for-loop with start, end and stepreturn [list[i] for i in range(start, end, step)]
+---+---+---+---+---+---+| P | y | t | h | o | n |+---+---+---+---+---+---+0 1 2 3 4 5 6-6 -5 -4 -3 -2 -1
从图中,我期望a[-4,-6,-1]是yP,但它是ty。
>>> a = "Python">>> a[2:4:1] # as expected'th'>>> a[-4:-6:-1] # off by 1'ty'
总是有效的是在字符或槽中思考,并使用索引作为半开间隔-右开如果是正步幅,左开如果是负步幅。
这样,我可以将a[-4:-6:-1]视为区间术语中的a(-6,-4]。
+---+---+---+---+---+---+| P | y | t | h | o | n |+---+---+---+---+---+---+0 1 2 3 4 5-6 -5 -4 -3 -2 -1
+---+---+---+---+---+---+---+---+---+---+---+---+| P | y | t | h | o | n | P | y | t | h | o | n |+---+---+---+---+---+---+---+---+---+---+---+---+-6 -5 -4 -3 -2 -1 0 1 2 3 4 5
def slicer(x, start=None, stop=None, step=None):""" Return the result of slicing list x.
See the part of list_subscript() in listobject.c that pertainsto when the indexing item is a PySliceObject."""
# Handle slicing index values of None, and a step value of 0.# See PySlice_Unpack() in sliceobject.c, which# extracts start, stop, step from a PySliceObject.maxint = 10000000 # A hack to simulate PY_SSIZE_T_MAXif step is None:step = 1elif step == 0:raise ValueError('slice step cannot be zero')
if start is None:start = maxint if step < 0 else 0if stop is None:stop = -maxint if step < 0 else maxint
# Handle negative slice indexes and bad slice indexes.# Compute number of elements in the slice as slice_length.# See PySlice_AdjustIndices() in sliceobject.clength = len(x)slice_length = 0
if start < 0:start += lengthif start < 0:start = -1 if step < 0 else 0elif start >= length:start = length - 1 if step < 0 else length
if stop < 0:stop += lengthif stop < 0:stop = -1 if step < 0 else 0elif stop > length:stop = length - 1 if step < 0 else length
if step < 0:if stop < start:slice_length = (start - stop - 1) // (-step) + 1else:if start < stop:slice_length = (stop - start - 1) // step + 1
# Cases of step = 1 and step != 1 are treated separatelyif slice_length <= 0:return []elif step == 1:# See list_slice() in listobject.cresult = []for i in range(stop - start):result.append(x[i+start])return resultelse:result = []cur = startfor i in range(slice_length):result.append(x[cur])cur += stepreturn result