Шаг 66.
Python: сборник рецептов.
Итераторы и генераторы. Итерирование в обратном порядке

    На этом шаге мы рассмотрим реализацию этой операции.

Задача

    Вы хотите проитерировать по последовательности в обратном порядке.

Решение

    Используйте встроенную функцию reversed(). Например:

>>> a = [1, 2, 3, 4]
>>> for x in reversed(a):
	print(x)

	
4
3
2
1
>>> 

    Обратная итерация сработает только в том случае, если объект имеет определенный размер или если в нем реализован специальный метод __reversed__(). Если ни одно из этих условий не выполнено, вы должны будете сначала конвертировать объект в список. Например:

# Выводит файл задом наперед 
f = open('somefile') 
for line in reversed(list(f)): 
    print(line, end='')

    Обратите внимание, что конвертирование итерируемого объекта в список может съесть много памяти, если список получится большим.

Обсуждение

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

class Countdown:
    def __init__(self, start):
        self.start = start

    # Прямой итератор
    def __iter__(self):
        n = self.start
        while n > 0:
            yield n
            n -= 1

    # Обратный итератор
    def __reversed__(self):
        n = 1
        while n <= self.start:
            yield n
            n += 1

    Определение обратного итератора делает код намного более эффективным, а также снимает необходимость предварительного помещения данных в список для выполнения итераций в обратном порядке.

    На следующем шаге мы рассмотрим определение генератора с дополнительным состоянием.




Предыдущий шаг Содержание Следующий шаг