[Python-ideas] Adding an optional function argument to all() and any() builtins

Steven D'Aprano steve at pearwood.info
Mon Nov 22 05:19:28 CET 2010


Ron Adam wrote:
> On 11/21/2010 01:39 PM, Andy Buckley wrote:
[...]
>> For example, this unclear code:
>>
>>      testval = False
>>      for i in mylist:
>>          if mytestfunction(i):
>>              testval = True
>>              break
>>      if testval:
>>          foo()
> 
> This has the advantage that it doesn't need to iterate the whole list. 
> Sometimes you can't beat a nice old fashion loop. ;-)

Both any() and all() have lazy semantics and will stop as early as 
possible. They will only traverse the entire list if they have to. 
There's no need to write your own function to get that behaviour.


> I would write it like this...
> 
>     def test_any(iterable, test=bool):
>         for i in iterable:
>             if test(i):
>                 return True
>         return False

That would be more easily written as:

def test_any(iterable, test=bool):
     return any(test(obj) for obj in iterable)

But of course that raises the question of what advantage test_any() has 
over an inline call to any(test(obj) for obj in iterable).


Aside: for what little it's worth, defaulting to bool as the test 
function causes a significant slow-down:

[steve at sylar ~]$ python3 -m timeit -s "L=[0]*1000000" "any(L)"
10 loops, best of 3: 28 msec per loop
[steve at sylar ~]$ python3 -m timeit -s "L=[0]*1000000" "any(bool(x) for x 
in L)"
10 loops, best of 3: 615 msec per loop


In fairness, some of that slow-down is due to the overhead of the 
generator expression itself:

[steve at sylar ~]$ python3 -m timeit -s "L=[0]*1000000" "any(x for x in L)"
10 loops, best of 3: 241 msec per loop

but it's best to avoid calling bool() unless you absolutely need an 
actual bool. test_any should probably be written as:

def test_any(iterable, test=None):
     if test: return any(test(obj) for obj in iterable)
     else: return any(iterable)


although my care-factor is insufficient to actually bother timing it :)



-- 
Steven




More information about the Python-ideas mailing list