Python的切片表示法是如何工作的?也就是说:当我编写[x:y:z]、a[:]、a]::2]等代码时,我如何理解哪些元素最终会出现在切片中?请在适当的地方附上参考资料。


另请参见:为什么切片和范围上限是互斥的?


当前回答

简单易懂:

在Python中,切片符号a[start:stop:step]可以用于从序列中选择一系列元素(例如列表、元组或字符串)。

起始索引是包括在切片中的第一个元素,

停止索引是从切片中排除的第一个元素,也是最后一个元素

步长值是切片元素之间的索引数。

例如,考虑以下列表:

a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

如果要选择a的所有元素,可以使用切片符号a[:]:

>>> a[:]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

如果我们想选择a的所有元素,但跳过其他元素,我们可以使用切片符号a[::2]:

>>> a[::2]
[0, 2, 4, 6, 8]

如果我们想选择从第三个元素(索引2)到第七个元素(索引号6)的所有元素,我们可以使用切片符号a[2:7]:

>>> a[2:7]
[2, 3, 4, 5, 6]

如果我们想选择从第三个元素(索引2)到第七个元素(索引号6)的所有元素,但跳过其他元素,我们可以使用切片符号a[2:7:2]:

>>> a[2:7:2]
[2, 4, 6]

如果我们想选择从第三个元素(索引2)到列表末尾的所有元素,我们可以使用切片符号a[2:]:

>>> a[2:]
[2, 3, 4, 5, 6, 7, 8, 9]

如果我们想选择从列表开头到第七个元素(索引6)的所有元素,我们可以使用切片符号a[:7]:

>>> a[:7]
[0, 1, 2, 3, 4, 5, 6]

如果您想了解有关切片表示法的更多信息,可以参考Python官方文档:链接1链接2

其他回答

我发现更容易记住它是如何工作的,然后我可以找出任何特定的开始/停止/步骤组合。

首先了解range()是很有启发性的:

def range(start=0, stop, step=1):  # Illegal syntax, but that's the effect
    i = start
    while (i < stop if step > 0 else i > stop):
        yield i
        i += step

从起点开始,一步一步递增,不要到达终点。非常简单。

关于消极步骤,需要记住的一点是,停止总是被排除的终点,无论它是高还是低。如果您希望相同的切片以相反的顺序进行,则单独进行反转会更为简单:例如,“abcde”[1:-2][::-1]从左侧切下一个字符,从右侧切下两个字符,然后反转。(另请参见reversed()。)

序列切片是相同的,只是它首先规范了负索引,并且它永远不能超出序列:

TODO:当abs(step)>1时,下面的代码出现了一个错误:“从不超出序列”;我认为我修补了它是正确的,但很难理解。

def this_is_how_slicing_works(seq, start=None, stop=None, step=1):
    if start is None:
        start = (0 if step > 0 else len(seq)-1)
    elif start < 0:
        start += len(seq)
    if not 0 <= start < len(seq):  # clip if still outside bounds
        start = (0 if step > 0 else len(seq)-1)
    if stop is None:
        stop = (len(seq) if step > 0 else -1)  # really -1, not last element
    elif stop < 0:
        stop += len(seq)
    for i in range(start, stop, step):
        if 0 <= i < len(seq):
            yield seq[i]

不要担心“无”的细节——只需记住,省略开始和/或停止总是正确的做法,以提供整个序列。

首先规范化负索引允许开始和/或停止从结尾独立计数:'abcde'[1:-2]=='abcde'[1:3]=='bc',尽管范围(1,-2)==[]。标准化有时被认为是“对长度取模”,但注意它只增加了一次长度:例如,“abcde”[-53:42]只是整个字符串。

如果你觉得切片中的负指数令人困惑,这里有一个非常简单的方法来考虑:用len-index替换负指数。例如,用len(list)-3替换-3。

说明切片在内部做什么的最佳方法是在实现此操作的代码中显示它:

def slice(list, start = None, end = None, step = 1):
  # Take care of missing start/end parameters
  start = 0 if start is None else start
  end = len(list) if end is None else end

  # Take care of negative start/end parameters
  start = len(list) + start if start < 0 else start
  end = len(list) + end if end < 0 else end

  # Now just execute a for-loop with start, end and step
  return [list[i] for i in range(start, end, step)]

以下是字符串索引的示例:

 +---+---+---+---+---+
 | H | e | l | p | A |
 +---+---+---+---+---+
 0   1   2   3   4   5
-5  -4  -3  -2  -1

str="Name string"

切片示例:[开始:结束:步骤]

str[start:end] # Items start through end-1
str[start:]    # Items start through the rest of the array
str[:end]      # Items from the beginning through end-1
str[:]         # A copy of the whole array

以下是示例用法:

print str[0] = N
print str[0:2] = Na
print str[0:7] = Name st
print str[0:7:2] = Nm t
print str[0:-1:2] = Nm ti

这只是为了一些额外的信息。。。考虑以下列表

>>> l=[12,23,345,456,67,7,945,467]

反转列表的其他几个技巧:

>>> l[len(l):-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]

>>> l[:-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]

>>> l[len(l)::-1]
[467, 945, 7, 67, 456, 345, 23, 12]

>>> l[::-1]
[467, 945, 7, 67, 456, 345, 23, 12]

>>> l[-1:-len(l)-1:-1]
[467, 945, 7, 67, 456, 345, 23, 12]

如果我们可以将切片与范围联系起来,这很容易理解,因为范围给出了索引。我们可以将切片分为以下两类:


1.无台阶或台阶>0。例如,[i:j]或[i:j:k](k>0)

假设序列为s=[1,2,3,4,5]。

如果0<i<len(s)和0<j<len,则[i:j:k]->范围(i,j,k)

例如,[0:3:2]->范围(0,3,2)->0,2

如果i>len或j>len,则i=len或j=len

例如,[0:100:2]->范围(0,len(s),2)->范围(0,5,2)->0,2,4

如果i<0或j<0,则i=max(0,len(s)+i)或j=max

例如,[0:-3:2]->范围(0,len(s)-3,2)->范围(0,2,2)->0

例如,[0:-1:2]->范围(0,len(s)-1,2)->范围(0,4,2)->0,2

如果未指定i,则i=0

例如,[:4:2]->范围(0,4,2)->范围(4,2)->0,2

如果未指定j,则j=len(s)

例如,[0::2]->范围(0,len(s),2)->范围(0,5,2)->0,2,4


2.步骤<0。例如,[i:j:k](k<0)

假设序列为s=[1,2,3,4,5]。

如果0<i<len(s)和0<j<len,则[i:j:k]->范围(i,j,k)

例如,[5:0:-2]->范围(5,0,-2)->5,3,1

如果i>len或j>len,则i=len(s)-1或j=len(s)-1

例如,[100:0:-2]->范围(len(s)-1,0,-2)->范围(4,0,-2)->4,2

如果i<0或j<0,则i=max(-1,len(s)+i)或j=max(-1len(s)+j)

例如,[-2:-10:-2]->range(len(s)-2,-1,-2)->range(3,-1,-1)->3,1

如果未指定i,则i=len(s)-1

例如,[:0:-2]->范围(len(s)-1,0,-2)->范围(4,0,-2)->4,2

如果未指定j,则j=-1

例如,[2::-2]->范围(2,-1,-2)->2,0

例如,[::-1]->range(len(s)-1,-1,-1)->range(4,-1,1)->4,3,2,1,0


总而言之