我正在尝试在Python中对列表进行反向切片,但返回一个空列表。但是当我尝试使用整个列表时,它可以正常工作。这里是否有什么遗漏?
l = [1,2,3,4,5,6,7,8]
l[::-1] = [8, 7, 6, 5, 4, 3, 2, 1] # <<< This worked fine.
l[2:5] = [3, 4, 5]
l[2:5:-1] = [] # <<< Expecting [5,4,3] here.
有什么线索吗?
语法始终为[开始:结束:步长]
,因此如果向后移动,则起点需要大于终点。还要记住它包括起点但不包括终点,因此在交换起点和终点后,需要减去1。
l[5:2:-1]= [6, 5, 4]
l[4:1:-1]= [5, 4, 3]
切片符号是[start:stop:step]
。这意味着“从start
开始,然后每次增加step
直到达到end
”。它类似于以下结构:
counter = 0
stop = 10
step = 1
while counter < stop:
print(counter)
counter += step
这将按预期生成0
到9
。
现在想象一下,如果我们尝试使用您正在使用的值:
counter = 2
stop = 5
step = -1
while counter < stop:
print(counter)
counter += step
2
,然后将其加上-1
得到1
,之后打印出1
并将其加上-1
得到0
,接着会变成-1
,-2
等等,永无止境。你必须手动停止程序才能阻止这个无限循环。start
或 stop
留空,如在 [:4]
或 [::-1]
中所示,这表示序列的开头或结尾,取决于 step
的规定。Python 会根据正数的 step
向前遍历序列, 根据负数的 step
向后遍历(使用 0
作为步长会产生错误)。>>> l[2::]
[3, 4, 5, 6, 7, 8]
>>> l[2::-1]
[3, 2, 1]
>>> l[:2:]
[1, 2]
>>> l[:2:-1]
[8, 7, 6, 5, 4]
start
、end
和step
(空的step
默认为1
),Python将只返回一个空序列。为什么 L[::-1]
返回的是一个反转后的列表,但是 L[2:5:-1]
却返回了空的 []
列表??
[start:stop:step]
中,如果缺少起始值,则始终将其设置为开始,而缺少的停止值则设置为列表的末尾。这个假设是不正确的,因为在 Python 中,如果您没有明确指定 start
和 stop
,Python 将根据 step
的符号以不同的方式替换缺失的 start
和 stop
值,在存在负的 step
值的情况下,将 start
设置为列表的结尾而不是开头。
当您在切片L[start:stop:step]
中不指定start
和/或stop
值(即使用L[::step]
)时,Python将按以下方式执行:
step
具有正值,则start
将设置为0
(并且stop
将设置为len(L)
)step
具有负值,则start
将设置为len(L)-1
。如果未指定stop
的值,则无法用切片表示,并且需要将切片定义值转换为range()
的参数。让我们提供一些代码来证明上面的内容是正确的,并通过其他方式解释与上述已经说明的相同(请参见代码中的注释)。以下代码使用Python的assert
语句来检查给定的比较是否显示正确的切片值,并在Python中使用slice
对象可用的.indices()
方法,为range()
返回所需的表示切片对象的列表索引的参数:
L = [1,2,3,4,5,6]
assert L[ : : ] == [1,2,3,4,5,6] # << OK. No AssertionError.
assert L[ : :-1] == L[len(L)-1:-len(L)-1:-1] == [6,5,4,3,2,1]
assert L[ : :-1] == [6,5,4,3,2,1] # << OK. No AssertionError.
assert L[2:5: ] == [3,4,5]
# ===
assert L[2: :-1] == [3,2,1]
# ^-- because with -1 step and decreasing i -= 1 starting with 0
# ^-- the condition (2+i > -1) for list index gives [3,2,1]
assert slice(2,None,-1).indices(len(L)) == (2,-1,-1)
# ^-- and because the None becomes -1 ( for use in range() )
# ===
assert L[ :5:-1] == []
# ^-- because with -1 step and decreasing i -= 1 starting with 0
# ^-- no list item will meet the condition (2+i > 5) for its index
assert slice(None,5,-1).indices(len(L)) == (5,5,-1)
# ^-- and because the None becomes 5 ( for use in range() )
# ===
assert L[2:5:-1] == []
# ^-- because with -1 step and decreasing i -= 1 starting with 0
# ^-- no list item will meet the condition (2+i > 5) for its index
assert slice(2,5,-1).indices(len(L)) == (2,5,-1)
# ^-- and because range(2,5,-1) does not return any values
# ^-- and because you are starting at 2 and stepping -1 trying to get
# to 5 ( you can't count backwards from 2 to 5 )
# ===
assert L[2:5][::-1] == [5,4,3] # it works in different square brackets
assert L[4:1:-1] == [5,4,3] # '-1' is not reversing, it is stepping
-1
иҖҢдёҚжҳҜеҖ’еәҸжқҘиҺ·еҫ—l[4:1:-1]
гҖӮ - Padraic Cunninghaml[2:5:2]
却可以工作,我很好奇。 - EdChump=l[2:] p[::-1]
。我原以为索引会变成匿名索引值,所以步进操作只需要起作用。 - EdChum