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


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


当前回答

在我看来,如果您按照以下方式查看Python字符串切片表示法(继续阅读),您将更好地理解和记忆它。

让我们使用以下字符串。。。

azString = "abcdefghijklmnopqrstuvwxyz"

对于不知道的人,可以使用符号azString[x:y]从azString创建任何子字符串

来自其他编程语言,这是常识受到损害的时候。x和y是什么?

为了寻找一种记忆技巧,我不得不坐下来运行了几个场景,帮助我记住x和y是什么,并帮助我在第一次尝试时正确地切分字符串。

我的结论是,x和y应该被视为围绕我们想要增加的字符串的边界索引。因此,我们应该将表达式视为azString[index1,index2],或者更清晰地视为azString[index_of_first_charactere,index_after_the_last_character]。

这是一个可视化的例子。。。

Letters   a b c d e f g h i j ...
         ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
             ┊           ┊
Indexes  0 1 2 3 4 5 6 7 8 9 ...
             ┊           ┊
cdefgh    index1       index2

因此,您所要做的就是将index1和index2设置为所需子字符串周围的值。例如,要获得子字符串“cdefgh”,可以使用azString[2:8],因为“c”左侧的索引是2,而“h”右侧的索引是8。

请记住,我们正在设置边界。这些边界是可以放置一些括号的位置,括号将像这样围绕子字符串。。。

a b[c d e f g h]i j公司

这个技巧一直有效,而且很容易记住。

其他回答

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   :
|--------------->
    <---------------|

我希望这将帮助您用Python建模列表。

参考:http://wiki.python.org/moin/MovingToPythonFromOtherLanguages

在找到这张很棒的桌子http://wiki.python.org/moin/MovingToPythonFromOtherLanguages

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]==4
Slice from rear:   :  -5  -4  -3  -2  -1   :
                                                b=a[:]
                                                b==[0,1,2,3,4,5] (shallow copy of a)

我个人认为这就像一个for循环:

a[start:end:step]
# for(i = start; i < end; i += step)

此外,请注意,start和end的负值是相对于列表末尾的,并且在上面的示例中通过given_index+a.shape[0]计算。

1.切片符号

为了简单起见,请记住切片只有一种形式:

s[start:end:step]

下面是它的工作原理:

s: 可以切片的物体start:开始迭代的第一个索引end:最后一个索引,请注意,最终的切片中不会包含结束索引step:每个步骤索引拾取元素

另一个重要的事情:所有开始、结束和步骤都可以省略!如果省略它们,则将使用它们的默认值:0,len(s),1。

因此,可能的变化如下:

# Mostly used variations
s[start:end]
s[start:]
s[:end]

# Step-related variations
s[:end:step]
s[start::step]
s[::step]

# Make a copy
s[:]

注意:如果start>=end(仅在步骤>0时考虑),Python将返回一个空切片[]。

2.陷阱

上面的部分解释了切片如何工作的核心特性,它将在大多数情况下工作。然而,可能会有陷阱,您应该注意,本部分将对它们进行解释。

负面指数

让Python学习者困惑的第一件事是索引可以是负数!不要惊慌:负指数意味着倒数。

例如:

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].

负阶跃

让事情更令人困惑的是,这一步也可能是消极的!

负步骤意味着向后迭代数组:从结束到开始,包括结束索引,从结果中排除开始索引。

注意:当step为负值时,start的默认值为len(s)(而end不等于0,因为s[::-1]包含s[0])。例如:

s[::-1]            # Reversed slice
s[len(s)::-1]      # The same as above, reversed slice
s[0:len(s):-1]     # Empty list

超出范围错误?

请注意:当索引超出范围时,切片不会引发IndexError!

如果索引超出范围,Python将根据情况尽量将索引设置为0或len。例如:

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 demonstration
In [1]: s = [i for i in range(10)]

In [2]: s
Out[2]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [3]: s[2:]   # From index 2 to last index
Out[3]: [2, 3, 4, 5, 6, 7, 8, 9]

In [4]: s[:8]   # From index 0 up to index 8
Out[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 order
Out[9]: [9, 7, 5, 3, 1]

In [11]: s[-2::-2] # All even numbers in reversed order
Out[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 list
Out[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

简单易懂:

在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