bool evaluations of generators vs lists
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Wed Feb 11 00:07:31 EST 2009
On Tue, 2009-02-10 at 12:50 -0800, Josh Dukes wrote:
>> The thing I don't understand is why a generator that has no iterable
>> values is different from an empty list. Why shouldn't bool ==
>> has_value?? Technically a list, a tuple, and a string are also objects
>> but if they lack values they're evaluated as False. It seems to me that
>> a generator is an object that intends to replace lists where lazy
>> evaluation would be more efficent. Here is one place where that's
>> definitely true.
Just in case it's not perfectly clear: until you call next() there is no
way to know whether the generator will yield any value or not -- and once
it does, it's lost until you explicitely save it.
This generator doesn't yield any value - but you have to wait for a while
if you call .next() on it, until eventually raises StopIteration:
(x for x in xrange(2000000000) if x>100000000000)
En Tue, 10 Feb 2009 19:25:47 -0200, Albert Hopkins
<marduk at letterboxes.org> escribió:
>> The main reason I'm interested in this is that it improves performance
>> immensely over boolean evaluation of large lists (as the attached code
>> shows). It seems to me if I could use find a good use for it in my
>> experimentation that someone else might also want to do the same thing
>> in real-world code.
>
> I don't understand what you mean by this. But if you really want to
> know if a generator is "non-empty":
>
> def non_empty(virgin_generator):
> try:
> virgin_generator.next() # note you just lost the first value
> return True
> except StopIteration:
> return False
>
> The only way to get around this is to put all the values of a generator
> inside a container (e.g. a list):
For a long generator you may not want to do that, also you may not want to
lose the next element. A variation of your function above is useful in
such cases:
py> def end_of_gen(g):
... """returns (False, next_element) when it exists or (True, None) when
it's
empty"""
... try: return False, g.next()
... except StopIteration: return True, None
...
py> g = (c for c in "Python" if c in "aeiou")
py> eog, c = end_of_gen(g)
py> eog
False
py> c
'o'
py> eog, c = end_of_gen(g)
py> eog
True
py> c
--
Gabriel Genellina
More information about the Python-list
mailing list