Ben Finney wrote: > "Carl Banks" <[EMAIL PROTECTED]> writes: > > > An iterator is not a sequence, and it's impossible to determine > > whether an iterator is "empty" in general, except by trying to get > > an item from it. [...] > > > > IMO, this is big time wart in the language. Iterators have no > > calculatable truth value; for many other types a truth value doesn't > > make sense (for instance: function objects, type objects, modules, > > user-defined types that don't bother with __nonzero__). Using such > > objects in a boolean context is almost always an error. > > It still seems like a reasonable thing for a programmer to do though, > even if the language doesn't currently support it. > > Would it make sense to *define* a truth value for iterators? Or at > least to enable those that *are* able to say "I'm empty" to do so in a > way that boolean contexts can interpret as "false"?
Again, it's impossible to tell if an iterator is empty in general except by trying to get an item. You could add a feature to iterators that fetches an item and stores it, but that would a. be a pain in the neck for everyone, and b. adversely affect iterators that depend on outside factors. > Perhaps allowing (but not requiring) an iterator object to grow a > 'len' method is the simplest way. I could live with some iterators defining __len__ or even __nonzero__, as long as iterators that couldn't determine these things threw an exception rather than returning a fake value. I'd rather no iterators did this, though, because having these options makes it likely that some programmers will write code supporting only "len-able iterators", thus hindering polymorphism unnecessarily. I'd rather people use iterators as iterators and not as temporally-challenged lists. However, it's certainly helpful sometimes to know if an iterator has any items left (say, to possibly avoid some initialization code). I don't think this should be a part of iterator protocol, but maybe it'd be nice if somewhere in the the standard library there was an iterator type such as this: class EmptySavvyIterator(object): noitem = object() def __init__(self,iterable): self.iterator = iter(iterable) self.storage = self.noitem def __iter__(self): return self def next(self): if self.storage is not self.noitem: item = self.storage self.storage = self.noitem return item return self.iterator.next() def empty(self): if self.storage is not self.noitem: return False try: self.storage = self.iterator.next() except StopIteration: return True return False # if you must... def __nonzero__(self): return not self.empty() Carl Banks -- http://mail.python.org/mailman/listinfo/python-list