1

考虑以下代码:

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

2 回答 2

8

第一次迭代,您将切片为-0,这与从 切片相同0。只有第二次迭代你切片为-1, then -2

也许您可以使用从负索引开始的范围:

for i in range(-len(a), 0):
    print a[-i:]
于 2013-03-23T23:03:19.457 回答
0

由于基于 0 的索引,反向切片在 Python 中不能完全对称。具体来说,不可能将 -0 与 0 区分开来。但是基于 0 的索引数组中的对称访问用例将规定,如果第 0 项是从左起第一个,那么第 -0 项(即负 0) 是从右数第一个,但由于 0 和 -0 是同一个实体,这会带来问题。

考虑列表索引的两个方向:

前进:第一项在位置 0,第二项在位置 1,...,最后一项在位置 n-1

向后:第一项在位置-1,第二项在-2,...,最后一项在位置-n

因此,负索引表示法是(length-index)的简写:collection[-i] == collection[len(collection) - i]

或者,并排,索引是:

[0, 1, 2,...,n-1]
[-n,..., -3, -2, -1 ]

上述两个指数实际上是相同的。

要执行对称操作,您的切片运算符需要正确考虑此索引方案:

原始切片a[0:i]== 从左端(0 处)开始的 i 个元素,步长为 1 ==a[0:i:1]

反向切片:从右端(-1)开始的 i 个元素,步长为-1

因此,另一端的正确切片将是a[-1:-1-i:-1]

请注意,此处的停止值是 i 的负数,偏移 -1 以说明基于 -1 的反向索引,这是必要的,因为我们使用基于前向的列表(例如 range 函数)生成 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]
于 2013-03-24T00:14:23.183 回答