for_some(),for_all()?
Raymond Hettinger
vze4rx4y at verizon.net
Fri Sep 24 00:47:20 EDT 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