Boolean tests [was Re: Attack a sacred Python Cow]
Steven D'Aprano
steve at REMOVE-THIS-cybersource.com.au
Wed Jul 30 22:54:41 EDT 2008
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
More information about the Python-list
mailing list