When you use a generator comprehension, you can only use the iterable once. For example.
>>> g = (i for i in xrange(10))
>>> min(g)
0
>>> max(g)
Traceback (most recent call last):File "<stdin>", line 1, in <module>
ValueError: max() arg is an empty sequence
Which is kind of annoying considering that works differently than list comprehensions.
You could do g = lambda (): (i for i in xrange(10))
to make it reusable, but then you have to do g ()
instead of g
(EDIT: The problem with this isn't that g ()
is too long to type, but that if a function expects an iterable, you can't tell it to do g ()
instead of g.__iter__()
). You could also do
class gObject(object):def __iter__(self): return (i for i in xrange(10))g = gObject()
but that is significantly longer than typing g = (i for i in xrange(10))
. Is there a shorter syntax than gObject
to accomplish this task?
Notes:
- We may assume that the iterable will not consume elements from other permanent iterables. For example, if I did
z = iter(xrange(10))
, I would not try to defineg = (i for i in z)
, since that could only work once (without cloningz
). g
will no longer be an iterator. Rather, it will now be an iterable. I am fine with that. Indeed, that is kind of the point.- It should work for infinite iterables. For example, a list comprehension would not work since it only works in finite cases.
- We may assume that any initialization costs are cheap, so rerunning the code defining
g
would not be an issue.