Почему я не могу отменить все итераторы в Python 3? - PullRequest
0 голосов
/ 16 октября 2019
  • Я могу позвонить reversed в списке.
  • Я могу позвонить reversed на range_iterator.
  • Я не могу позвонить reversed на list_iterator.
  • Я не могу вызвать reversed для itertools.accumulate.

Почему я могу вызвать reversed для списка и range_iterator, но не для list_iterator илиитератор itertools?

>>> reversed(itertools.accumulate(reversed(x), lambda x, y: x + y))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'itertools.accumulate' object is not reversible

1 Ответ

1 голос
/ 16 октября 2019

Если вы прочитаете документы , вы увидите, что reversed работает на любом объекте со следующими характеристиками:

имеет метод __reversed__() или поддерживает последовательностьпротокол (метод __len__() и метод __getitem__() с целочисленными аргументами, начинающимися с 0)

Обратите внимание, это означает, что не может использовать reversed для range_iterator,но вы можете на обычном range объекте.

>>> reversed(iter(range(10)))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'range_iterator' object is not reversible
>>> reversed(range(10))
<range_iterator object at 0x105bcac90>

Также обратите внимание, что вы обычно не можете полностью изменить итераторы , это последовательность итерацийкоторые обычно обратимы. Или что-нибудь, что поддерживает его через ловушку магического метода __reversed__(), и итераторы, как правило, не имеют ни одного (обычно только с поддержкой __iter__ и __next__)

...