为什么反转迭代器需要索引为-2而不是1?

Car*_*ven 0 python iterator

当我尝试反转迭代器时,就像我在下面的例子中所做的那样,我实际上得到了两次打印的结果:

class TestIterator:

  def __init__(self):
    self.list = ['Alice', 'Bob', 'Charlie']

  def __iter__(self):
    self.idx = len(self.list) - 1
    return self

  def __next__(self):
    try:
      res = self.list[self.idx]
    except IndexError:
      raise StopIteration
    self.idx -= 1
    return res

names = TestIterator()

for name in names:
  print(name)
Run Code Online (Sandbox Code Playgroud)

结果:

Charlie
Bob
Alice
Charlie
Bob
Alice
Run Code Online (Sandbox Code Playgroud)

在上面的结果中,名称打印两次.我希望它以这种方式打印:

Charlie
Bob
Alice
Run Code Online (Sandbox Code Playgroud)

然而,奇怪的是,经过一段时间的徘徊,我注意到,如果我有self.idx -= 2,它只打印一次,但序列仍然是错误的.例:

...
  def __next__(self):
    try:
      res = self.list[self.idx]
    except IndexError:
      raise StopIteration
    self.idx -= 2
    return res
...
Run Code Online (Sandbox Code Playgroud)

这打印:

Charlie
Alice
Bob
Run Code Online (Sandbox Code Playgroud)

我不明白为什么我在索引上减去2以使迭代器正常工作.为什么它会这样?

Ale*_*all 6

当您使用self.idx -= 1,self.idx经过了值2, 1, 0, -1, -2, -3, -4,用IndexError-4.-1, -2, -3都是Python中的有效索引.

使用时self.idx -= 2,self.idx浏览值2, 0, -2, -4.所以它只打印三个值,但顺序错误.

不要except IndexError用于此目的,使用if self.idx < 0或其他东西.

还养成了使用print语句调试程序的习惯.A print(self.idx)可能会揭示你发生了什么.