了解切片符号


3279

我需要一个关于Python切片符号的很好的解释(引用是一个加号)。

对我而言,此表示法需要一些注意。

它看起来非常强大,但是我还没有完全了解它。

Answers:


4493

真的很简单:

a[start:stop]  # items start through stop-1
a[start:]      # items start through the rest of the array
a[:stop]       # items from the beginning through stop-1
a[:]           # a copy of the whole array

还有一个step值,可以与以上任何一种一起使用:

a[start:stop:step] # start through not past stop, by step

要记住的关键点是该:stop值表示不在所选切片中的第一个值。所以,之间的差stopstart是选择的元素的数量(如果step是1,默认值)。

另一个功能是startstop可能是负数,这意味着它从数组的末尾而不是开头开始计数。所以:

a[-1]    # last item in the array
a[-2:]   # last two items in the array
a[:-2]   # everything except the last two items

同样,step可能为负数:

a[::-1]    # all items in the array, reversed
a[1::-1]   # the first two items, reversed
a[:-3:-1]  # the last two items, reversed
a[-3::-1]  # everything except the last two items, reversed

如果项目数量少于您的要求,Python对程序员很友好。例如,如果您要求a[:-2]并且a仅包含一个元素,则会得到一个空列表,而不是一个错误。有时您会更喜欢该错误,因此您必须意识到这种情况可能会发生。

slice()对象的关系

[]上面的代码中实际上将切片运算符与slice()使用:符号的对象一起使用(仅在内有效[]),即:

a[start:stop:step]

等效于:

a[slice(start, stop, step)]

切片对象也表现略有不同,这取决于参数的个数,同样range(),即两个slice(stop)slice(start, stop[, step])支持。要跳过指定给定参数的操作,可以使用None,例如a[start:]等于a[slice(start, None)]a[::-1]等于a[slice(None, None, -1)]

尽管:基于的符号对于简单切片非常有帮助,但是slice()对象的显式使用简化了切片的编程生成。


122
切片内置类型会返回一个副本,但这不是通用的。值得注意的是,切片NumPy数组会返回一个与原始共享内存的视图。
贝尼·切尔尼亚夫斯基-帕斯金

43
投票证明这是一个很好的答案,但它漏了一件事:您可以替代None任何空白区域。例如[None:None]制作完整副本。当您需要使用变量指定范围的结束并且需要包括最后一项时,此功能很有用。
Mark Ransom

6
真正让我烦恼的是python说,当您不设置开始和结束时,它们默认设置为0和序列长度。因此,从理论上讲,当您使用“ abcdef” [::-1]时,应将其转换为“ abcdef” [0:6:-1],但是这两个表达式不会获得相同的输出。自创建该语言以来,我觉得python文档中缺少某些内容。
axell13

6
而且我知道将“ abcdef” [::-1]转换为“ abcdef” [6:-7:-1],因此,最好的解释方法是:让len为序列的长度。如果step为正,则start和end的默认值为0和len否则,如果步骤是否定的,用于开始和结束的缺省值len个和- len个 - 1
axell13

4
由于stackoverflow.com/questions/39241529/…已被标记为重复,因此添加带有delwrt slice表示法的节是否有意义?特别是,del arr[:]不是立即显而易见的(“ arr [:]复制,del删除该副本

536

Python的教程谈论它(稍微向下滚动,直到你得到关于切片的部分)。

ASCII艺术图也有助于记住切片的工作方式:

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1

记住切片如何工作的一种方法是将索引视为指向字符之间的指针,第一个字符的左边缘编号为0。然后,n个字符的字符串的最后一个字符的右侧边缘具有索引n


10
此建议对积极的步伐有效,但对消极的步伐无效。从图中,我希望a[-4,-6,-1]是,yP但是它是ty。始终起作用的是思考字符或空位,并使用索引作为半开间隔–如果正向跨步则向右打开,如果负向跨步则向左打开。
aguadopd

但是没有办法从头开始折叠为空集(就像从头开始折叠一样x[:0]),因此必须对小数组进行特殊情况处理。:/
endolith '19

412

列举语法允许的可能性:

>>> seq[:]                # [seq[0],   seq[1],          ..., seq[-1]    ]
>>> seq[low:]             # [seq[low], seq[low+1],      ..., seq[-1]    ]
>>> seq[:high]            # [seq[0],   seq[1],          ..., seq[high-1]]
>>> seq[low:high]         # [seq[low], seq[low+1],      ..., seq[high-1]]
>>> seq[::stride]         # [seq[0],   seq[stride],     ..., seq[-1]    ]
>>> seq[low::stride]      # [seq[low], seq[low+stride], ..., seq[-1]    ]
>>> seq[:high:stride]     # [seq[0],   seq[stride],     ..., seq[high-1]]
>>> seq[low:high:stride]  # [seq[low], seq[low+stride], ..., seq[high-1]]

当然,如果(high-low)%stride != 0,则终点将比稍低high-1

如果stride为负,则由于我们递减计数,因此顺序有所更改:

>>> seq[::-stride]        # [seq[-1],   seq[-1-stride],   ..., seq[0]    ]
>>> seq[high::-stride]    # [seq[high], seq[high-stride], ..., seq[0]    ]
>>> seq[:low:-stride]     # [seq[-1],   seq[-1-stride],   ..., seq[low+1]]
>>> seq[high:low:-stride] # [seq[high], seq[high-stride], ..., seq[low+1]]

扩展切片(带有逗号和省略号)通常仅由特殊的数据结构(例如NumPy)使用;基本序列不支持它们。

>>> class slicee:
...     def __getitem__(self, item):
...         return repr(item)
...
>>> slicee()[0, 1:2, ::5, ...]
'(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)'

实际上仍然遗漏了一些东西,例如,如果我键入“ apple” [4:-4:-1]我得到了“ elp”,python会将-4转换为1可能是?
liyuan

需要注意的是反引号赞成不赞成的repr
wjandrea

@liyuan实现的类型__getitem__是;您的示例等同于apple[slice(4, -4, -1)]
chepner

320

上面的答案不讨论切片分配。要了解切片分配,在ASCII艺术中添加另一个概念很有帮助:

                +---+---+---+---+---+---+
                | P | y | t | h | o | n |
                +---+---+---+---+---+---+
Slice position: 0   1   2   3   4   5   6
Index 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[2:4]
 ['T','h']
>>> p[2:4] = ['t','r']
>>> p
 ['P','y','t','r','o','n']

切片分配的第三个规则是,分配的列表(可迭代)不必具有相同的长度。索引切片被简单地切出,并被分配的内容全部替换:

>>> p = ['P','y','t','h','o','n'] # Start over
>>> p[2:4] = ['s','p','a','m']
>>> p
 ['P','y','s','p','a','m','o','n']

习惯最棘手的部分是分配给空片。使用启发式1和2可以很容易地索引一个空片:

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

请注意,由于我们没有更改分片的第二个数字(4),因此即使我们分配给空分片,插入的项目也总是紧靠'o'堆积。因此,空切片分配的位置是非空切片分配的位置的逻辑扩展。

进行一点备份,当您继续进行我们从头开始计算切片的过程时,会发生什么?

>>> 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[5:4]
 []
>>> p[6:4]
 []

使用切片,一旦完成,就完成了;它不会开始向后切片。在Python中,除非您通过使用负数明确要求它们,否则您不会获得负面的进步。

>>> p[5:3:-1]
 ['n','o']

“一旦完成,就完成了”规则有一些奇怪的后果:

>>> p[4:4]
 []
>>> p[5:4]
 []
>>> p[6:4]
 []
>>> p[6]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

实际上,与索引相比,Python切片非常防错:

>>> p[100:200]
 []
>>> p[int(2e99):int(1e99)]
 []

有时这会派上用场,但也会导致一些奇怪的行为:

>>> p
 ['P', 'y', 't', 'h', 'o', 'n']
>>> p[int(2e99):int(1e99)] = ['p','o','w','e','r']
>>> p
 ['P', 'y', 't', 'h', 'o', 'n', 'p', 'o', 'w', 'e', 'r']

根据您的应用程序,这可能……或可能不是……您所希望的!


以下是我的原始答案的文字。它对很多人都有用,所以我不想删除它。

>>> r=[1,2,3,4]
>>> r[1:1]
[]
>>> r[1:1]=[9,8]
>>> r
[1, 9, 8, 2, 3, 4]
>>> r[1:1]=['blah']
>>> r
[1, 'blah', 9, 8, 2, 3, 4]

这也可以澄清切片和索引之间的区别。


246

解释Python的切片符号

总之,冒号(:)在标符号(subscriptable[subscriptarg])使切片符号-它具有可选参数,startstopstep

sliceable[start:stop:step]

Python切片是一种计算快速的方法,可以有条不紊地访问部分数据。我认为,即使是一名中级Python程序员,这也是该语言必须熟悉的一个方面。

重要定义

首先,让我们定义一些术语:

start:切片的开始索引,它将包含此索引处的元素,除非它与stop相同,默认为0,即第一个索引。如果为负,则表示从头开始n

stop:切片的结束索引,包含该索引处的元素,默认为要切片的序列的长度,即直到并包括结束。

步骤:索引增加的数量,默认为1。如果为负,则按相反方向切片。

索引如何工作

您可以使这些正数或负数中的任何一个。正数的含义很简单,但对于负数,就像在Python索引,向后从最终的计数启动停止,并为一步,你只需递减索引。此示例来自文档的教程,但我对其进行了稍微修改,以指示每个索引引用序列中的哪个项目:

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
   0   1   2   3   4   5 
  -6  -5  -4  -3  -2  -1

切片如何工作

要将切片符号与支持它的序列一起使用,必须在序列后的方括号中至少包含一个冒号(根据Python数据模型,该括号实际上实现__getitem__了序列的方法)。

切片符号的工作方式如下:

sequence[start:stop:step]

并记得startstopstep有默认值,因此要访问默认值,只需省略参数。

从列表(或支持字符串的任何其他序列,如字符串)中获取最后九个元素的切片表示法如下所示:

my_list[-9:]

看到此内容时,我将括号中的部分读为“从末尾到第9位”。(实际上,我在心理上将其缩写为“ -9,on”)

说明:

完整的符号是

my_list[-9:None:None]

并替换为默认值(实际上,当step为负数时,stop默认值为-len(my_list) - 1,因此None对于stop而言,实际上仅意味着它会到达执行此操作的最后一个步骤):

my_list[-9:len(my_list):1]

冒号:是什么将告诉Python,你给它一个切片,而不是一个常规的索引。这就是为什么在Python 2中制作列表的浅表副本的惯用方式是

list_copy = sequence[:]

清除它们的方法是:

del my_list[:]

(Python 3获得了list.copyand list.clear方法。)

step为负数时,默认值startstop更改

默认情况下,当step参数为空(或None)时,会将其分配给+1

但是,您可以传入一个负整数,列表(或大多数其他标准可切片)将从头到尾切成片。

因此,负片将更改startand 的默认值stop

在来源中确认

我希望鼓励用户阅读源代码和文档。切片对象源代码和此逻辑可在此处找到。首先我们确定是否step为负:

 step_is_negative = step_sign < 0;

如果是这样,则下限是-1 指我们一直切到开始并包括起点,上限是长度减去1,这意味着我们从末尾开始。(请注意,此语义-1不同从一个-1用户可能通过在Python索引指示最后项)。

if (step_is_negative) {
    lower = PyLong_FromLong(-1L);
    if (lower == NULL)
        goto error;

    upper = PyNumber_Add(length, lower);
    if (upper == NULL)
        goto error;
}

否则step为正,下界将为零,上限(我们将达到但不包括在内)的是切片列表的长度。

else {
    lower = _PyLong_Zero;
    Py_INCREF(lower);
    upper = length;
    Py_INCREF(upper);
}

然后,我们可能需要应用默认设置startstop-那么默认的start时计算为上限step是否定的:

if (self->start == Py_None) {
    start = step_is_negative ? upper : lower;
    Py_INCREF(start);
}

stop,下限:

if (self->stop == Py_None) {
    stop = step_is_negative ? lower : upper;
    Py_INCREF(stop);
}

给您的切片起一个描述性的名字!

您可能会发现,将形成切片与将切片传递给list.__getitem__方法分开很有用(这就是方括号所做的事情)。即使您并不陌生,它也可以使您的代码更具可读性,以便其他可能必须阅读您的代码的人可以更轻松地了解您的操作。

但是,您不能只将一些用冒号分隔的整数分配给变量。您需要使用slice对象:

last_nine_slice = slice(-9, None)

第二个参数,None,是必需的,使得第一参数被解释为所述start参数否则这将是stop自变量

然后可以将slice对象传递给序列:

>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]

有趣的是,范围也可以切片:

>>> range(100)[last_nine_slice]
range(91, 100)

内存注意事项:

由于Python列表切片在内存中创建了新对象,因此需要注意的另一个重要功能是itertools.islice。通常,您需要遍历一个切片,而不仅仅是在内存中静态创建它。islice对此很完美。一个警告,它不支持负的参数startstop或者step,如果这是一个问题,您可能需要计算指标或反向迭代提前。

length = 100
last_nine_iter = itertools.islice(list(range(length)), length-9, None, 1)
list_last_nine = list(last_nine_iter)

现在:

>>> list_last_nine
[91, 92, 93, 94, 95, 96, 97, 98, 99]

列表切片可以复制的事实是列表本身的功能。如果要切片高级对象(例如Pandas DataFrame),则它可能会返回原始视图,而不是副本。


145

当我第一次看到切片语法时,有几件事对我来说并不立即显而易见:

>>> x = [1,2,3,4,5,6]
>>> x[::-1]
[6,5,4,3,2,1]

颠倒序列的简单方法!

如果出于某种原因,您想要按相反的顺序进行第二个项目:

>>> x = [1,2,3,4,5,6]
>>> x[::-2]
[6,4,2]

100

在Python 2.7中

用Python切片

[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

当您说[a:b:c]时,您要说的是根据c的符号(向前或向后),从a开始,到b结束(不包括bth索引处的元素)。使用上面的索引规则,请记住,您只会在此范围内找到元素:

-len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1

但是这个范围在两个方向上都无限地继续:

...,-len -2 ,-len-1,-len, -len+1, -len+2, ..., 0, 1, 2,3,4 , len -1, len, len +1, len+2 , ....

例如:

             0    1    2   3    4   5   6   7   8   9   10   11
             a    s    t   r    i   n   g
    -9  -8  -7   -6   -5  -4   -3  -2  -1

如果您对a,b和c的选择允许您在使用上方a,b,c的规则遍历时与上述范围重叠,则您将获得一个包含元素的列表(在遍历期间被触摸)或一个空列表。

最后一件事:如果a和b相等,那么您还会得到一个空列表:

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

2
另一个有趣的例子:a = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]; a[:-2:-2]导致[9]
Deviacium

96

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)

65

使用了一点之后,我意识到最简单的描述是它与for循环中的参数完全相同...

(from:to:step)

它们都是可选的:

(:to:step)
(from::step)
(from:to)

然后,负索引只需要您将字符串的长度添加到负索引即可理解。

无论如何这对我有用...


52

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

首先了解它是有启发性的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

从头开始start,以递增step,不达到stop。很简单。

要记住的关于负步长的事情stop是,无论是更高还是更低,始终是被排除的终点。如果您想以相反的顺序切割同一片,则分开进行反转会更清洁:例如'abcde'[1:-2][::-1]从左侧切出一个字符,从右侧切出两个字符,然后反转。(另请参见reversed()。)

序列切片相同,不同之处在于它首先对负索引进行规范化,并且永远不会超出序列范围:

待办事项:当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]

不必担心is None细节-请记住,省略start和/或stop始终做正确的事情可以为您提供整个序列。

首先,通过对负索引进行规范化,可以从开始到结束独立地对开始和/或停止进行计数:'abcde'[1:-2] == 'abcde'[1:3] == 'bc'尽管range(1,-2) == []。标准化有时被认为是“对长度取模”,但请注意,它仅将长度加一次:例如'abcde'[-53:42],只是整个字符串。


3
this_is_how_slicing_works是不一样的蟒蛇片。EG [0, 1, 2][-5:3:3]在python中将获得[0],但将list(this_is_how_slicing_works([0, 1, 2], -5, 3, 3))获得[1]。
Eastsun

@Eastsun糟糕,您是对的!一个更清楚的例子:range(4)[-200:200:3] == [0, 3]但是list(this_is_how_slicing_works([0, 1, 2, 3], -200, 200, 3)) == [2]。我if 0 <= i < len(seq):只是尝试简单地实现“永不超出顺序”,但对于步骤> 1是错误的。我将在今天晚些时候用测试将其重写。
贝尼·切尔尼亚夫斯基-帕斯金,

40

我自己使用“元素之间的索引点”方法来思考它,但是描述它有时可以帮助他人获得它的一种方法是:

mylist[X:Y]

X是所需的第一个元素的索引。
Y是您不需要的第一个元素的索引。


40
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


38

Python切片符号:

a[start:end:step]
  • 对于startend,负值被解释为相对于序列的末尾。
  • 对于正指标end指示的位置后,要包含的最后一个元素。
  • 空白值的默认设置如下:[+0:-0:1]
  • 使用否定步骤会颠倒对start和的解释。end

该符号扩展到(numpy)个矩阵和多维数组。例如,要切片整个列,可以使用:

m[::,0:2:] ## slice the first two columns

切片包含数组元素的引用,而不是副本。如果要为数组创建单独的副本,可以使用deepcopy()


34

您还可以使用切片分配从列表中删除一个或多个元素:

r = [1, 'blah', 9, 8, 2, 3, 4]
>>> r[1:4] = []
>>> r
[1, 2, 3, 4]

33

这只是一些额外的信息...请考虑以下列表

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

33

这是我教新手切片的方法:

了解索引和切片之间的区别:

Wiki Python的这张惊人图片清楚地区分了索引编制和切片。

在此处输入图片说明

这是一个包含六个元素的列表。为了更好地了解切片,请将该列表视为一组六个盒子放在一起。每个盒子中都有一个字母。

索引就像处理盒子的内容。您可以检查任何框的内容。但是您不能一次检查多个框的内容。您甚至可以更换包装箱中的物品。但是您不能将两个球放在一个盒子中,也不能一次更换两个球。

In [122]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']

In [123]: alpha
Out[123]: ['a', 'b', 'c', 'd', 'e', 'f']

In [124]: alpha[0]
Out[124]: 'a'

In [127]: alpha[0] = 'A'

In [128]: alpha
Out[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

切片就像处理盒子本身。您可以拿起第一个盒子并将其放在另一个桌子上。要拿起盒子,您只需要知道盒子的开始和结束位置即可。

您甚至可以拾取前三个框,最后两个框或1到4之间的所有框。因此,如果您知道开始和结束,则可以选择任何一组框。这些位置称为开始位置和停止位置。

有趣的是,您可以一次替换多个盒子。您也可以在需要的地方放置多个盒子。

In [130]: alpha[0:1]
Out[130]: ['A']

In [131]: alpha[0:1] = 'a'

In [132]: alpha
Out[132]: ['a', 'b', 'c', 'd', 'e', 'f']

In [133]: alpha[0:2] = ['A', 'B']

In [134]: alpha
Out[134]: ['A', 'B', 'c', 'd', 'e', 'f']

In [135]: alpha[2:2] = ['x', 'xx']

In [136]: alpha
Out[136]: ['A', 'B', 'x', 'xx', 'c', 'd', 'e', 'f']

切片步骤:

到现在为止,您一直在不断挑选箱子。但是有时您需要离散地接机。例如,您可以每隔两个框取一次。您甚至可以从头开始每隔三个盒子拿起。此值称为步长。这代表您连续的拾音器之间的差距。如果您要从头到尾选择框,则步长应该为正,反之亦然。

In [137]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']

In [142]: alpha[1:5:2]
Out[142]: ['b', 'd']

In [143]: alpha[-1:-5:-2]
Out[143]: ['f', 'd']

In [144]: alpha[1:5:-2]
Out[144]: []

In [145]: alpha[-1:-5:2]
Out[145]: []

Python如何找出缺失的参数:

切片时,如果遗漏任何参数,Python会尝试自动找出它。

如果您检查CPython的源代码,则会发现一个名为PySlice_GetIndicesEx()的函数,该函数可以为任何给定参数找出切片的索引。这是Python中的逻辑等效代码。

此函数采用Python对象和可选参数进行切片,并返回所请求切片的开始,停止,步长和切片长度。

def py_slice_get_indices_ex(obj, start=None, stop=None, step=None):

    length = len(obj)

    if step is None:
        step = 1
    if step == 0:
        raise Exception("Step cannot be zero.")

    if start is None:
        start = 0 if step > 0 else length - 1
    else:
        if start < 0:
            start += length
        if start < 0:
            start = 0 if step > 0 else -1
        if start >= length:
            start = length if step > 0 else length - 1

    if stop is None:
        stop = length if step > 0 else -1
    else:
        if stop < 0:
            stop += length
        if stop < 0:
            stop = 0 if step > 0 else -1
        if stop >= length:
            stop = length if step > 0 else length - 1

    if (step < 0 and stop >= start) or (step > 0 and start >= stop):
        slice_length = 0
    elif step < 0:
        slice_length = (stop - start + 1)/(step) + 1
    else:
        slice_length = (stop - start - 1)/(step) + 1

    return (start, stop, step, slice_length)

这就是切片背后的智能。由于Python具有称为slice的内置函数,因此您可以传递一些参数并检查其计算缺失参数的技巧。

In [21]: alpha = ['a', 'b', 'c', 'd', 'e', 'f']

In [22]: s = slice(None, None, None)

In [23]: s
Out[23]: slice(None, None, None)

In [24]: s.indices(len(alpha))
Out[24]: (0, 6, 1)

In [25]: range(*s.indices(len(alpha)))
Out[25]: [0, 1, 2, 3, 4, 5]

In [26]: s = slice(None, None, -1)

In [27]: range(*s.indices(len(alpha)))
Out[27]: [5, 4, 3, 2, 1, 0]

In [28]: s = slice(None, 3, -1)

In [29]: range(*s.indices(len(alpha)))
Out[29]: [5, 4]

注意:这篇文章最初是在我的博客Python切片背后的情报中撰写的。


29

通常,编写带有很多硬编码索引值的代码会导致可读性和维护混乱。例如,如果一年后返回代码,您将对其进行查看,并想知道编写代码时的想法。显示的解决方案只是一种更清晰地说明代码实际运行方式的方式。通常,内置slice()创建一个slice对象,该对象可在允许slice的任何地方使用。例如:

>>> items = [0, 1, 2, 3, 4, 5, 6]
>>> a = slice(2, 4)
>>> items[2:4]
[2, 3]
>>> items[a]
[2, 3]
>>> items[a] = [10,11]
>>> items
[0, 1, 10, 11, 4, 5, 6]
>>> del items[a]
>>> items
[0, 1, 4, 5, 6]

如果您有切片实例s,则可以分别通过查看其s.start,s.stop和s.step属性来获取有关其的更多信息。例如:

>>> a = slice(10, 50, 2)
>>> a.start
10
>>> a.stop
50
>>> a.step
2
>>>

25

1.切片符号

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

s[start:end:step]

这是它的工作方式:

  • s:可以切片的对象
  • start:开始迭代的第一个索引
  • end:最后一个索引,请注意,end索引将不包含在结果切片中
  • step:选择每个step索引元素

另一种进口的东西:所有的startendstep可以省略!如果省略了它们,它们的默认值将被使用:0len(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(仅考虑step>0),Python将返回一个空slice []

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也可能是负面的!

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

:当步骤为负值,默认值startlen(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

超出范围错误?

惊奇: 当索引超出范围时,slice不会引发IndexError!

如果索引超出范围,Python将尽力将索引设置为0len(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 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

24

先前的答案没有讨论使用著名的NumPy包可以实现的多维数组切片:

切片也可以应用于多维数组。

# Here, a is a NumPy array

>>> a
array([[ 1,  2,  3,  4],
       [ 5,  6,  7,  8],
       [ 9, 10, 11, 12]])
>>> a[:2, 0:3:2]
array([[1, 3],
       [5, 7]])

的“ :2”逗号在第一维和操作之前,“ 0:3:2”逗号在第二维操作之后。


4
温馨提示:您不能在Python list上执行此操作,而只能array在Numpy上执行
Mars Lee

15
#!/usr/bin/env python

def slicegraphical(s, lista):

    if len(s) > 9:
        print """Enter a string of maximum 9 characters,
    so the printig would looki nice"""
        return 0;
    # print " ",
    print '  '+'+---' * len(s) +'+'
    print ' ',
    for letter in s:
        print '| {}'.format(letter),
    print '|'
    print " ",; print '+---' * len(s) +'+'

    print " ",
    for letter in range(len(s) +1):
        print '{}  '.format(letter),
    print ""
    for letter in range(-1*(len(s)), 0):
        print ' {}'.format(letter),
    print ''
    print ''


    for triada in lista:
        if len(triada) == 3:
            if triada[0]==None and triada[1] == None and triada[2] == None:
                # 000
                print s+'[   :   :   ]' +' = ', s[triada[0]:triada[1]:triada[2]]
            elif triada[0] == None and triada[1] == None and triada[2] != None:
                # 001
                print s+'[   :   :{0:2d} ]'.format(triada[2], '','') +' = ', s[triada[0]:triada[1]:triada[2]]
            elif triada[0] == None and triada[1] != None and triada[2] == None:
                # 010
                print s+'[   :{0:2d} :   ]'.format(triada[1]) +' = ', s[triada[0]:triada[1]:triada[2]]
            elif triada[0] == None and triada[1] != None and triada[2] != None:
                # 011
                print s+'[   :{0:2d} :{1:2d} ]'.format(triada[1], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]]
            elif triada[0] != None and triada[1] == None and triada[2] == None:
                # 100
                print s+'[{0:2d} :   :   ]'.format(triada[0]) +' = ', s[triada[0]:triada[1]:triada[2]]
            elif triada[0] != None and triada[1] == None and triada[2] != None:
                # 101
                print s+'[{0:2d} :   :{1:2d} ]'.format(triada[0], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]]
            elif triada[0] != None and triada[1] != None and triada[2] == None:
                # 110
                print s+'[{0:2d} :{1:2d} :   ]'.format(triada[0], triada[1]) +' = ', s[triada[0]:triada[1]:triada[2]]
            elif triada[0] != None and triada[1] != None and triada[2] != None:
                # 111
                print s+'[{0:2d} :{1:2d} :{2:2d} ]'.format(triada[0], triada[1], triada[2]) +' = ', s[triada[0]:triada[1]:triada[2]]

        elif len(triada) == 2:
            if triada[0] == None and triada[1] == None:
                # 00
                print s+'[   :   ]    ' + ' = ', s[triada[0]:triada[1]]
            elif triada[0] == None and triada[1] != None:
                # 01
                print s+'[   :{0:2d} ]    '.format(triada[1]) + ' = ', s[triada[0]:triada[1]]
            elif triada[0] != None and triada[1] == None:
                # 10
                print s+'[{0:2d} :   ]    '.format(triada[0]) + ' = ', s[triada[0]:triada[1]]
            elif triada[0] != None and triada[1] != None:
                # 11
                print s+'[{0:2d} :{1:2d} ]    '.format(triada[0],triada[1]) + ' = ', s[triada[0]:triada[1]]

        elif len(triada) == 1:
            print s+'[{0:2d} ]        '.format(triada[0]) + ' = ', s[triada[0]]


if __name__ == '__main__':
    # Change "s" to what ever string you like, make it 9 characters for
    # better representation.
    s = 'COMPUTERS'

    # add to this list different lists to experement with indexes
    # to represent ex. s[::], use s[None, None,None], otherwise you get an error
    # for s[2:] use s[2:None]

    lista = [[4,7],[2,5,2],[-5,1,-1],[4],[-4,-6,-1], [2,-3,1],[2,-3,-1], [None,None,-1],[-5,None],[-5,0,-1],[-5,None,-1],[-1,1,-2]]

    slicegraphical(s, lista)

您可以运行此脚本并进行实验,以下是我从脚本中获得的一些示例。

  +---+---+---+---+---+---+---+---+---+
  | C | O | M | P | U | T | E | R | S |
  +---+---+---+---+---+---+---+---+---+
  0   1   2   3   4   5   6   7   8   9   
 -9  -8  -7  -6  -5  -4  -3  -2  -1 

COMPUTERS[ 4 : 7 ]     =  UTE
COMPUTERS[ 2 : 5 : 2 ] =  MU
COMPUTERS[-5 : 1 :-1 ] =  UPM
COMPUTERS[ 4 ]         =  U
COMPUTERS[-4 :-6 :-1 ] =  TU
COMPUTERS[ 2 :-3 : 1 ] =  MPUT
COMPUTERS[ 2 :-3 :-1 ] =  
COMPUTERS[   :   :-1 ] =  SRETUPMOC
COMPUTERS[-5 :   ]     =  UTERS
COMPUTERS[-5 : 0 :-1 ] =  UPMO
COMPUTERS[-5 :   :-1 ] =  UPMOC
COMPUTERS[-1 : 1 :-2 ] =  SEUM
[Finished in 0.9s]

当使用否定步骤时,请注意答案右移1。


14

我的大脑似乎很高兴接受lst[start:end]包含start-th项的内容。我什至可以说这是一个“自然的假设”。

但是偶尔会有一个疑问浮出水面,我的大脑要求确保它不含end-th元素。

在这些时刻,我依靠这个简单的定理:

for any n,    lst = lst[:n] + lst[n:]

这个漂亮的属性告诉我,lst[start:end]它不包含end-th项,因为它在中lst[end:]

注意,该定理对任何一个n都成立。例如,您可以检查

lst = range(10)
lst[:-42] + lst[-42:] == lst

返回True


12

我认为,如果以以下方式(继续阅读)看待它,您将更好地理解和记住Python字符串切片表示法。

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

azString = "abcdefghijklmnopqrstuvwxyz"

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

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

在寻求一种记忆技术时,我不得不坐下来并运行几种方案,该技术将帮助我记住x和y是什么,并帮助我在第一次尝试中正确地分割字符串。

我的结论是,x和y应该被视为包围我们要附加的字符串的边界索引。因此,我们应该将表达式视为azString[index1, index2]或什至更清晰azString[index_of_first_character, 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。

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

ab [ cdefgh ] ij

该技巧始终有效,并且易于记忆。



10

在Python中,切片的最基本形式如下:

l[start:end]

where l是某个集合,start是一个包含索引,并且end是一个排斥索引。

In [1]: l = list(range(10))

In [2]: l[:5] # First five elements
Out[2]: [0, 1, 2, 3, 4]

In [3]: l[-5:] # Last five elements
Out[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 one
Out[7]: [0, 1, 2, 3, 4, 5, 6, 7, 8]

In [8]: l[-3:] # Take the last three elements
Out[8]: [7, 8, 9]

切片时可以提供超出范围的索引,例如:

In [9]: l[:20] # 20 is out of index bounds, and l[20] will raise an IndexError exception
Out[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 exception
Out[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]: l
Out[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]: l
Out[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_copy
Out[15]: True

如果在执行赋值操作时省略了开始索引和结束索引,则集合的全部内容将被引用的副本代替:

In [20]: l[:] = list('hello...')

In [21]: l
Out[21]: ['h', 'e', 'l', 'l', 'o', '.', '.', '.']

除了基本切片之外,还可以应用以下符号:

l[start:end:step]

where l是一个集合,start是一个包含索引,end是一个排他索引,并且step是一个可用于获取第n个项目的跨度l

In [22]: l = list(range(10))

In [23]: l[::2] # Take the elements which indexes are even
Out[23]: [0, 2, 4, 6, 8]

In [24]: l[1::2] # Take the elements which indexes are odd
Out[24]: [1, 3, 5, 7, 9]

使用step提供了一个有用的技巧来反转Python中的集合:

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

step下面的示例也可以使用负整数:

In[28]:  l[::-2]
Out[28]: [9, 7, 5, 3, 1]

但是,对使用负值step可能会造成混乱。此外,为了Python化,应避免使用startend以及step在一个片。如果需要这样做,请考虑分两次进行(一次进行切片,另一次进行大跨步)。

In [29]: l = l[::2] # This step is for striding

In [30]: l
Out[30]: [0, 2, 4, 6, 8]

In [31]: l = l[1:-1] # This step is for slicing

In [32]: l
Out[32]: [2, 4, 6]

10

我想添加一个世界您好!这个例子为初学者解释了切片的基础。这对我帮助很大。

我们来看一个包含六个值的列表['P', 'Y', 'T', 'H', 'O', 'N']

+---+---+---+---+---+---+
| P | Y | T | H | O | N |
+---+---+---+---+---+---+
  0   1   2   3   4   5

现在,该列表中最简单的部分就是其子列表。符号是[<index>:<index>],关键是这样阅读:

[ start cutting before this index : end cutting before this index ]

现在,如果您[2:5]从上面的列表中切出一部分,就会发生这种情况:

        |           |
+---+---|---+---+---|---+
| P | Y | T | H | O | N |
+---+---|---+---+---|---+
  0   1 | 2   3   4 | 5

您在具有index的元素之前进行了切割,在具有index 的元素之前进行2另一切割。因此,结果将是这两个削减之间的一个片段,一个清单。5['T', 'H', 'O']


10

我个人认为它像一个for循环:

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

此外,请注意,对于负值startend相对于所述列表的末尾和上述通过计算在示例given_index + a.shape[0]


8

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

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

5

如果您认为切片中的负索引令人困惑,这是一种很简单的思考方法:只需将负索引替换为len - index。因此,例如,将-3替换为len(list) - 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)]

4

基本切片技术是定义起点,终点和步长-也称为步幅。

首先,我们将创建一个值列表以用于切片。

创建两个要切片的列表。第一个是从1到9的数字列表(列表A)。第二个也是一个数字列表,从0到9(列表B):

A = list(range(1, 10, 1)) # Start, stop, and step
B = list(range(9))

print("This is List A:", A)
print("This is List B:", B)

索引A中的数字3和B中的数字6。

print(A[2])
print(B[6])

基本切片

用于切片的扩展索引语法为aList [start:stop:step]。start参数和step参数都默认为none-唯一需要的参数是stop。您是否注意到这类似于使用范围定义列表A和B的方式?这是因为slice对象代表由range(开始,停止,步进)指定的索引集。Python 3.4文档。

如您所见,仅定义stop将返回一个元素。由于开始默认为无,因此这意味着只检索一个元素。

请注意,第一个元素是索引0,而不是索引索引1。这就是为什么我们在此练习中使用2个列表的原因。列表A的元素根据顺序位置编号(第一个元素为1,第二个元素为2,依此类推),而列表B的元素为将用于为其编号的数字(第一个元素为[0],第一个元素为[0],等等。)。

使用扩展的索引语法,我们检索值的范围。例如,所有值都用冒号检索。

A[:]

要检索元素的子集,需要定义开始位置和停止位置。

给定模式aList [start:stop],从列表A中检索前两个元素。


3

我认为Python教程图(在其他各种答案中被引用)不是很好,因为该建议对积极的步伐有效,但对消极的步伐却无效。

这是图:

 +---+---+---+---+---+---+
 | 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  
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.