请考虑以下代码:
>>> a = [0, 1, 2]
>>> for i in range(len(a)):
>>> print a[0:i]
[]
[0]
[0, 1]
但是,当我翻转代码从列表的另一端获取切片时,它不再有效:
>>> for i in range(len(a)):
>>> print a[-i:]
[0, 1, 2]
[2]
[1, 2]
使第二段代码工作的唯一方法似乎是颠倒列表,第一种方式,并在打印之前反转每一段。有一个更好的方法吗?我有时使用这种类型的循环,我希望我的代码尽可能干净。
编辑:在两个循环中,我从左到右迭代。如果我为第二个循环翻转迭代方向,它也可以工作。如果我翻转第一个循环的迭代方向,它也会与第二个循环有相同的打嗝:
>>> for i in range(len(a)):
>>> print a[i-1::-1]
[2, 1, 0]
[0]
[1, 0]
答案 0 :(得分:8)
第一次迭代,您正在切片为-0
,这与从0
切片相同。只有第二次迭代才会切换为-1
,然后切换为-2
。
也许你可以使用从负指数开始的范围:
for i in range(-len(a), 0):
print a[-i:]
答案 1 :(得分:0)
由于基于0的索引,反向切片在Python中不能完全对称。具体来说,不可能将-0与0区分开。但是,基于0的索引数组中的对称访问用例将指示如果第0项是从左边开始,那么第0项(即,负0)是右起第一个,但由于0和-0是同一个实体,这就产生了问题。
考虑列表索引的两个方向:
转发:第一项位于第0位,第二项位于第1位,......,最后一项位于第n-1位
向后:第一项位于-1,第二项位于-2,......,最后一项位于-n
负指数表示法因此是(长度 - 索引)的速记:collection[-i] == collection[len(collection) - i]
或者,并排,索引是:
[0, 1, 2,...,n-1]
[-n,..., -3, -2, -1 ]
如果上述两个指数实际上都是相同的。
要执行对称操作,切片运算符需要正确考虑此索引方案:
原始广告:a[0:i]
== i元素来自左端(0),步长为1 == a[0:i:1]
反向切片:i元素来自右端(位于-1),步长 -1 。
因此,来自另一端的正确切片将是a[-1:-1-i:-1]
请注意,这里的停止值是i的负数,偏移-1以考虑基于-1的反向索引,这是必要的,因为我们使用基于前向的列表生成i(例如范围函数) 。)
a = range(3) # [0,1,2]
for i in range(len(a)):
# forward case, next to backward case
print a[:i], a[-1:-1-i:-1]
# [] []
# [0] [2]
# [0, 1] [2, 1]