FWIW, I partially withdraw my observation that reiterability is a special case of cloneability. It is true that if you have cloneability you have reiterability. But I hadn't realized that reiterability is sometimes easier than cloneability! Cloning a generator function at an arbitrary point is not doable; but cloning a generator function at the start would be as easy as saving the function and its arguments. But this doesn't make me any more comfortable with the idea of adding reiterability as an iterator feature (even optional). An iterator represents the rest of the sequence of values it will generate. But if we add reiterability into the mix, an iterator represents two different sequences: its "full" sequence, accessible via its reiter() method (or whatever it would be called), and its "current" sequence. The latter may be different, because when you get passed an iterator, whoever passed it might already have consumed some items; this affects the "current" sequence but not the sequence returned by reiter(). (Cloning doesn't have this problem, but its other problems make up for this.) If you prefer to see a code sample explaining the problem: consider a consumer of a reiterable iterator: def printwice(it): for x in it: print x for x in it.reiter(): print x Now suppose the following code that calls it: r = range(10) it = iter(r) # assume this is reiterable it.next() # skip first item printwice(it) This prints 1...9 followed by 0...9 !!! The solution using cloning wouldn't have this problem: def printwice(it): it2 = it.clone() for x in it: print x for x in it2: print x With reiter() it becomes hard to explain what the input requirements are for the function to work correctly; effectively, it would require a "virginal" (== has never been used :-) reiterable iterator. So we might as well require a container! If you don't have a container but you have a description of a series, Alex's Reiterable can easily fix this: class Reiterable: def __init__(self, func, *args): self.func, self.args = func, args def __iter__(self): return self.func(*self.args) This should be called with e.g. a generator function and an argument list for it. --Guido van Rossum (home page: http://www.python.org/~guido/)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4