I'm looking for a way to reverse a generator object. I know how to reverse sequences:
foo = imap(seq.__getitem__, xrange(len(seq)-1, -1, -1))
But is something similar possible with a generator as the input and a开发者_Python百科 reversed generator as the output (len(seq) stays the same, so the value from the original sequence can be used)?
You cannot reverse a generator in any generic way except by casting it to a sequence and creating an iterator from that. Later terms of a generator cannot necessarily be known until the earlier ones have been calculated.
Even worse, you can't know if your generator will ever hit a StopIteration exception until you hit it, so there's no way to know what there will even be a first term in your sequence.
The best you could do would be to write a reversed_iterator function:
def reversed_iterator(iter):
return reversed(list(iter))
EDIT: You could also, of course, replace reversed in this with your imap based iterative version, to save one list creation.
reversed(list(input_generator))
is probably the easiest way.
There's no way to get a generator's values in "reverse" order without gathering all of them into a sequence first, because generating the second item could very well rely on the first having been generated.
You have to walk through the generator anyway to get the first item so you might as well make a list. Try
reversed(list(g))
where g
is a generator.
reversed(tuple(g))
would work as well (I didn't check to see if there is a significant difference in performance).
def reverseGenerator(gen):
new = [i for i in gen]
yield new[::-1][0]
new.pop()
yield from reverseGenerator(i for i in new)
精彩评论