我需要在Python的切片表示法上有一个很好的解释(引用是一个加号)。
对我而言,这种符号需要一点点提升。
它看起来非常强大,但我还没有完全理解它。
我需要在Python的切片表示法上有一个很好的解释(引用是一个加号)。
对我而言,这种符号需要一点点提升。
它看起来非常强大,但我还没有完全理解它。
它非常简单:
a[start:end] # items start through end-1
a[start:] # items start through the rest of the array
a[:end] # items from the beginning through end-1
a[:] # a copy of the whole array
还有 step
值,可以与上述任何一个一起使用:
a[start:end:step] # start through not past end, by step
要记住的关键点是 :end
value表示第一个值 不 在选定的切片中。所以,两者之间的区别 end
和 start
是选择的元素数量(如果 step
是1,默认值)。
另一个特点是 start
要么 end
可能是一个 负 数字,这意味着它从数组的末尾而不是从开头算起。所以:
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
只包含一个元素,您将得到一个空列表而不是错误。有时您会更喜欢错误,因此您必须意识到这可能会发生。
它非常简单:
a[start:end] # items start through end-1
a[start:] # items start through the rest of the array
a[:end] # items from the beginning through end-1
a[:] # a copy of the whole array
还有 step
值,可以与上述任何一个一起使用:
a[start:end:step] # start through not past end, by step
要记住的关键点是 :end
value表示第一个值 不 在选定的切片中。所以,两者之间的区别 end
和 start
是选择的元素数量(如果 step
是1,默认值)。
另一个特点是 start
要么 end
可能是一个 负 数字,这意味着它从数组的末尾而不是从开头算起。所以:
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
只包含一个元素,您将得到一个空列表而不是错误。有时您会更喜欢错误,因此您必须意识到这可能会发生。
该 Python教程 谈论它(向下滚动一下,直到你得到关于切片的部分)。
ASCII艺术图也有助于记住切片的工作方式:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5 6
-6 -5 -4 -3 -2 -1
记住切片如何工作的一种方法是将索引视为指向 之间 字符,第一个字符的左边缘编号为0.然后是字符串的最后一个字符的右边缘 ñ 字符有索引 ñ。
列举语法允许的可能性:
>>> 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 `item`
...
>>> slicee()[0, 1:2, ::5, ...]
'(0, slice(1, 2, None), slice(None, None, 5), Ellipsis)'
上面的答案不讨论切片分配:
>>> 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]
这也可以澄清切片和索引之间的区别。
解释Python的切片表示法
简而言之,冒号(:
)下标符号(subscriptable[subscriptarg]
)制作切片符号 - 具有可选参数, start
, stop
, step
:
sliceable[start:stop:step]
Python切片是一种有条不紊地访问部分数据的计算速度快的方法。在我看来,即使是一个中级Python程序员,它也是必须熟悉的语言的一个方面。
首先,让我们定义一些术语:
开始: 切片的起始索引,它将包括此索引处的元素,除非它与之相同 停止,默认为0,即第一个索引。如果它是否定的,则意味着开始
n
从最后的项目。停止: 切片的结束索引,确实如此 不 包含此索引处的元素,默认为要切片的序列的长度,即直到并包括结尾。
步: 索引增加的数量,默认为1.如果它是负数,则表示您正在反向切片。
您可以制作任何正数或负数。正数的含义很简单,但对于负数,就像Python中的索引一样,你从最后的数字向后计算 开始 和 停止,为了 步,你只需减少索引。这个例子是 来自文档的教程,但我稍微修改了它,以指示每个索引引用的序列中的哪个项目:
+---+---+---+---+---+---+
| P | y | t | h | o | n |
+---+---+---+---+---+---+
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1
要使用带有支持它的序列的切片表示法,必须在序列后面的方括号中包含至少一个冒号(实际上 实施 __getitem__
根据Python数据模型的序列方法。)
切片表示法的工作方式如下:
sequence[start:stop:step]
并回想一下,有默认值 开始, 停止,和 步,所以要访问默认值,只需省略参数。
从列表中获取最后九个元素的切片表示法(或任何其他支持它的序列,如字符串)将如下所示:
my_list[-9:]
当我看到这个时,我将括号中的部分读作“从结尾到结尾的第9个”。 (实际上,我在精神上将其缩写为“-9,on”)
完整的符号是
my_list[-9:None:None]
并替换默认值(实际上是 step
是消极的, stop
默认是 -len(my_list) - 1
所以 None
对于停止真的只是意味着它去任何结束步骤():
my_list[-9:len(my_list):1]
该 结肠, :
是什么告诉Python你给它一个切片而不是常规索引。这就是为什么在Python 2中制作浅表列表的惯用方法是
list_copy = sequence[:]
清除它们是:
del my_list[:]
(Python 3获得了一个 list.copy
和 list.clear
方法。)
step
是负数,默认值为 start
和 stop
更改默认情况下,当 step
参数是空的(或 None
),它被分配给 +1
。
但是你可以传入一个负整数,并且列表(或大多数其他标准的可切片)将从末尾切换到开头。
因此,负片会更改默认值 start
和 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); }
然后,我们可能需要应用默认值 start
和 stop
- 默认然后为 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__
方法 (这就是方括号的作用)。即使您不是新手,它也会使您的代码更具可读性,以便其他可能必须阅读您的代码的人可以更容易地理解您正在做的事情。
但是,您不能只将一些以冒号分隔的整数分配给变量。您需要使用切片对象:
last_nine_slice = slice(-9, None)
第二个论点, None
,是必需的,所以第一个参数被解释为 start
论据 否则就是了 stop
论据。
然后,您可以将切片对象传递给序列:
>>> 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
这是完美的。需要注意的是,它不支持负面论据 start
, stop
, 要么 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这样的高级对象,它可能会返回原始视图,而不是副本。
当我第一次看到切片语法时,有些事情对我来说并不是很明显:
>>> 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]
找到了这张伟大的餐桌 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)
在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]
稍微使用它之后,我意识到最简单的描述是它与for循环中的参数完全相同...
(from:to:step)
其中任何一个都是可选的
(:to:step)
(from::step)
(from:to)
那么负索引只需要你将字符串的长度添加到负索引来理解它。
无论如何这对我有用......