On Wed, 30 Jul 2008 20:55:03 +0100, Matthew Woodcraft wrote: > On the other hand, iterators provide a clear example of problems with > "if x": __nonzero__ for iterators (in general) returns True even if they > are 'empty'.
How do you propose telling whether an iterator is empty? That's a generic problem with any sort of lazy function. You don't know if it has finished unless you try grabbing data from it. > For example, this function (which attempts to avoid making an expensive > call when not necessary) is buggy, but easy to write if you've been > taught that "if x" will work with any kind of object. > > def frob(widgets, power): > if widgets: > frobber = Frobber(power) # expensive call > for widget in widgets: > frobber.frob(widget) AFAIK there's no great solution to this problem. It's inherent in the way lazy functions work. Certainly you can't replace the call to "if widgets" with "if len(widgets)", because iterators don't have a length. However, there is a good (but not great) solution: def frob(widgets, power): widgets = iter(widgets) # in case widgets is a sequence try: first = widgets.next() except StopIteration: # empty iterator, nothing to do return None frobber = Frobber(power) # expensive call frobber.frob(widget) for widget in widgets: frobber.frob(widget) -- Steven -- http://mail.python.org/mailman/listinfo/python-list