for_some(),for_all()?

Raymond Hettinger vze4rx4y at verizon.net
Fri Sep 24 06:47:20 CEST 2004


> > For pure speed, the following is faster and gives short-circuit behavior:
> >
> > >>> from itertools import ifilter
> > >>> def any(seq, pred=None):
> > ...     for elem in ifilter(pred, seq):
> > ...         return True
> > ...     return False

[Steven Bethard]
> So, the other one also has short-circuit behavior:

Right.  It was the reduce(operator.__or__) version that didn't short-circuit.


> >>> def any(seq, pred=bool):
> ...     return True in imap(pred, seq)
> ...
> >>> def pred(x):
> ...     return x > 3
> ...
> >>> i = iter(range(10))
> >>> any(i, pred)
> True
> >>> list(i)
> [5, 6, 7, 8, 9]
>
> Could you explain what makes the second one faster?  I'm guessing it's
> something like that comparing True to each element in the iterable costs more
> than binding each element in the iterable to elem...?

Close.  The imap() version has two layers of iteration:

     for elem in seq:
          yield pred(elem)

     for elem in imapresults:
          if elem == True:
               return True
     return False

The ifilter() version has only one layer:

      for elem in seq:
            if pred(elem):
                  yield elem

Note, it make look like there is an outer layer in the ifilter() version, but
closer inspection shows that it never runs more than one iteration:

     for elem in ifilterresults:
            return True       # because this returns, the for never loops back
     return False



Raymond Hettinger





More information about the Python-list mailing list