Как реализован Rangeiterator в Python? - PullRequest
1 голос
/ 22 марта 2012
>>> reversed(xrange(100))
<rangeiterator object at 0xb72aab78>
>>> it = reversed(xrange(100)).__iter__()
>>> it
<rangeiterator object at 0xb72aa4d0>
>>> next(it)
99

Как я могу реализовать что-то подобное в Python?Чтобы быть более конкретным, как я могу создать итератор, который можно было бы перевернуть, не сделав список в памяти, прежде чем он мог бы быть перевернут?

Ответы [ 3 ]

3 голосов
/ 22 марта 2012

По сути, вы реализуете магический метод __reversed__ в коллекции.

Логика для xrange выглядит примерно так:

def __reversed__(self):
    return iter(xrange(stop - 1, start - 1, step * -1))

Существуетнет хитрости - вам нужно знать, как создать обратный итератор.Python не делает это для вас.

1 голос
/ 22 марта 2012

Если ваш итератор реализует метод __reversed__(), он будет использоваться встроенным reversed(). xrange() возвращает итераторы, которые это делают.

0 голосов
/ 24 марта 2016

reversed будет работать с двумя типами объектов:

  • последовательность (например, list)
  • итератор с магическим методом __reversed__

Если у вас есть пользовательская последовательность, и вы можете взять len() этой последовательности, вы можете пойти - иначе вам нужно добавить магический метод __len__;если вы не можете (например, потому что длина неизвестна), то вы не можете ее лениво перевернуть.

Если у вас есть пользовательский итератор, убедитесь, что у него есть __reversed__ магический метод: __reversed__ должен вернутьновый итератор, возвращающийся назад;Опять же, если вы не можете предоставить один (например, потому что длина неизвестна), то вы не можете лениво изменить его.

Примечание : для получения дополнительной информации о создании пользовательских итераций см. thisответить .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...