According to the blog post here, an any() + generator expression should run quicker than a for loop, and it seems like his reasoning makes sense.
But I've tried to use this method (albeit on some other function), but it seems to take a longer time to run than an explicit for loop.
def with_loop(a, b):
for x in xrange(1, b):
if x * a % b == 1: return True
return False
def with_generator(a, b):
return any(x * a % b == 1 for x in xrange(1, b))
Basically the code loops through all the numbers from 1 to b to find whether the number a has a modular inverse.
The times I got from running the functions are:
>>> from timeit import Timer as T
>>> T(lambda : with_generator(100, 300)).repeat(number = 100000)
[3.4041796334919923, 3.6303230626526215, 3.6714475531563266]
>>> T(lambda : with_loop(100, 300)).repeat(number = 100000)
[2.1977450660490376, 2.2083902291327604, 2.1905292602997406]
>>> T(lambda : with_generator(101, 300)).repeat(number = 100000)
[1.213779524696747, 1.2228346702509043, 1.2216941170634072]
>>> T(lambda : with_loop(101, 300)).repeat(number = 100000)
[0.7431202233722161, 0.7444361146951906, 0.7525384471628058]
with_generator(100,300) returns False and with_generator(101,300) returns True.
It seems that with_generator always takes a longer time to run than with_loop. Is there any reason for this?
EDIT: Is there any other shorter or more elegant way of rewriting with_loop so that we achieve similar or better performance? Thanks!