[Python-Dev] product()

Guido van Rossum guido at python.org
Sat Oct 25 23:36:20 EDT 2003

> > These are close to what ABC does with quantifiers.  There, you can
> > write
> >
> >   IF EACH x IN sequence HAS x > 0: ...
> >
> > ABC has the additional quirk that if there's an ELSE branch, you can
> > use x in it (as a "counter-example").
> >
> > In Python, you could write this as
> >
> >   if alltrue(x > 0 for x in sequence): ...
> >
> > but the current design doesn't expose x to the else branch.
> Right -- it would return the condition being tested, x>0, when non-true,
> so just a False; there is no natural way for it to get the underlying
> object on which it's testing it.  This is somewhat the same problem as
> Peter Norvig's original Top(10) accumulator example: if you just pass to
> it the iterator of the comparison keys, it can't collect the 10 items with
> the highest comparison keys.
> Maybe
>     alltrue(sequence, pred=lambda x: x>0)
> might be better (pred would default to None meaning to test the items
> in the first argument, the iterator, for true/false directly):
> def alltrue(seq, pred=None):
>     if pred is None:
>         def pred(x): return x
>         def wrap(x): return x
>     else:
>         class wrap(object):
>             def __init__(self, x): self.counterexample = x
>             def __nonzero__(self): return False
>     for x in seq:
>         if not pred(x): return wrap(x)
>     else:
>         return True
> or something like that (I do think we need the wrap class, so that
> alltrue can return an object that evaluates to false but still allows
> the underlying "counter-example" to be retrieved if needed).
> Use, of course, would have to be something like:
> allpositives = alltrue(sequence, pred=lambda x: x>0)
> if allpositives: print "wow, all positives!"
> else: print "nope, some nonpositives, e.g.", allpositives.counterexample
> Unfortunately, this usage is pushing at TWO not-strengths of Python:
> no neat way to pass an unnamed predicate (lambda ain't really all
> that neat...) AND no assignment-as-expression.  So, I don't think it
> would really catch on all that much.

Yeah.  An explicit for loop sounds much better in cases where we want
to know which x failed the test.  Let alltrue() be as simple as
originally proposed.

Do we need allfalse() and anytrue() and anyfalse() too?  These can all
easily be gotten by judicious use of 'not'.  I think ABC has EACH,
SOME and NO (why not all four? who knows).

--Guido van Rossum (home page: http://www.python.org/~guido/)

More information about the Python-Dev mailing list