Python的切片表示法是如何工作的?也就是说:当我编写[x:y:z]、a[:]、a]::2]等代码时,我如何理解哪些元素最终会出现在切片中?请在适当的地方附上参考资料。
另请参见:为什么切片和范围上限是互斥的?
Python的切片表示法是如何工作的?也就是说:当我编写[x:y:z]、a[:]、a]::2]等代码时,我如何理解哪些元素最终会出现在切片中?请在适当的地方附上参考资料。
另请参见:为什么切片和范围上限是互斥的?
当前回答
我自己使用“元素之间的索引点”方法来思考它,但描述它的一种方式有时有助于其他人获得它:
mylist[X:Y]
X是所需的第一个元素的索引。Y是不需要的第一个元素的索引。
其他回答
基本的切片技术是定义起点、终点和步长(也称为步幅)。
首先,我们将创建一个用于切片的值列表。
创建两个要切片的列表。第一个是从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的方式类似?这是因为切片对象表示由范围(开始、停止、步骤)指定的索引集。
如您所见,仅定义stop返回一个元素。由于start默认为none,这意味着只检索一个元素。
需要注意的是,第一个元素是索引0,而不是索引1。这就是为什么我们在本练习中使用两个列表。列表A的元素根据序号位置进行编号(第一个元素是1,第二个元素是2,等等),而列表B的元素是用于对其进行索引的数字(对于第一个元素,[0],等等)。
通过扩展索引语法,我们可以检索一系列值。例如,使用冒号检索所有值。
A[:]
要检索元素的子集,需要定义开始和停止位置。
给定模式aList[start:stop],从列表A中检索前两个元素。
使用一点后,我意识到最简单的描述是它与for循环中的参数完全相同。。。
(from:to:step)
其中任何一项都是可选的:
(:to:step)
(from::step)
(from:to)
然后,负索引只需要将字符串的长度添加到负索引中即可理解它。
不管怎样,这对我来说都很有效。。。
这里有一个简单的记忆方法,可以记住它是如何工作的:
S L*I*C*E*切片的“i”位于第一位,代表包容,“e”排在最后,代表独占。
所以array[j:k]将包括第j个元素,并排除第k个元素。
切片规则如下:
[lower bound : upper bound : step size]
I-将上限和下限转换为公共符号。
II-然后检查步长是正值还是负值。
(i) 如果步长为正值,则上限应大于下限,否则将打印空字符串。例如:
s="Welcome"
s1=s[0:3:1]
print(s1)
输出:
Wel
但是,如果我们运行以下代码:
s="Welcome"
s1=s[3:0:1]
print(s1)
它将返回一个空字符串。
(ii)如果步长为负值,则上限应小于下限,否则将打印空字符串。例如:
s="Welcome"
s1=s[3:0:-1]
print(s1)
输出:
cle
但如果我们运行以下代码:
s="Welcome"
s1=s[0:5:-1]
print(s1)
输出将为空字符串。
因此,在代码中:
str = 'abcd'
l = len(str)
str2 = str[l-1:0:-1] #str[3:0:-1]
print(str2)
str2 = str[l-1:-1:-1] #str[3:-1:-1]
print(str2)
在第一个str2=str[l-1:0:-1]中,上限小于下限,因此打印dcb。
然而,在str2=str[l-1:-1:-1]中,上限不小于下限(将下限转换为负值,即-1:因为最后一个元素的索引是-1和3)。
我有点沮丧,因为找不到一个准确描述切片功能的在线源代码或Python文档。
我接受了Aaron Hall的建议,阅读了CPython源代码的相关部分,并编写了一些Python代码,这些代码执行切片与CPython中的切片类似。我已经用Python 3对整数列表进行了数百万次随机测试。
您可能会发现我的代码中对CPython中相关函数的引用很有用。
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 pertains
to 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_MAX
if step is None:
step = 1
elif step == 0:
raise ValueError('slice step cannot be zero')
if start is None:
start = maxint if step < 0 else 0
if 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.c
length = len(x)
slice_length = 0
if start < 0:
start += length
if start < 0:
start = -1 if step < 0 else 0
elif start >= length:
start = length - 1 if step < 0 else length
if stop < 0:
stop += length
if stop < 0:
stop = -1 if step < 0 else 0
elif stop > length:
stop = length - 1 if step < 0 else length
if step < 0:
if stop < start:
slice_length = (start - stop - 1) // (-step) + 1
else:
if start < stop:
slice_length = (stop - start - 1) // step + 1
# Cases of step = 1 and step != 1 are treated separately
if slice_length <= 0:
return []
elif step == 1:
# See list_slice() in listobject.c
result = []
for i in range(stop - start):
result.append(x[i+start])
return result
else:
result = []
cur = start
for i in range(slice_length):
result.append(x[cur])
cur += step
return result