Обратный генератор Python - PullRequest
       9

Обратный генератор Python

17 голосов
/ 13 октября 2009

Я ищу способ повернуть объект генератора. Я знаю, как изменить последовательность:

foo = imap(seq.__getitem__, xrange(len(seq)-1, -1, -1))

Но возможно ли нечто подобное с генератором на входе и инвертированным генератором на выходе (len (seq) остается неизменным, поэтому можно использовать значение из исходной последовательности)?

Ответы [ 3 ]

24 голосов
/ 13 октября 2009

Вы не можете инвертировать генератор любым общим способом, кроме как приведением его к последовательности и созданием итератора из этого. Более поздние условия генератора не могут быть известны, пока не будут рассчитаны более ранние.

Еще хуже, вы не можете знать, попадет ли когда-либо ваш генератор в исключение StopIteration, пока вы не нажмете его, поэтому нет никакого способа узнать, какой будет даже первый член вашей последовательности.

Лучшее, что вы можете сделать, - написать функцию reversed_iterator:

def reversed_iterator(iter):
    return reversed(list(iter))

РЕДАКТИРОВАТЬ: Вы также можете, конечно, заменить обратное в этом на вашу итеративную версию на основе imap, чтобы сохранить одно создание списка.

6 голосов
/ 13 октября 2009

reversed(list(input_generator)) вероятно самый простой способ.

Невозможно получить значения генератора в «обратном» порядке, не собрав все сначала в последовательность, потому что генерация второго элемента вполне может опираться на сгенерированный первый.

4 голосов
/ 13 октября 2009

Вам все равно придется пройти через генератор, чтобы получить первый предмет, чтобы вы могли составить список. Попробуйте

reversed(list(g))

где g - генератор.

reversed(tuple(g))

также будет работать (я не проверял, есть ли существенная разница в производительности).

...