[Tutor] creating a range above & below a given number

Emile van Sebille emile at fenx.com
Sun Jun 7 21:34:51 CEST 2009


On 6/7/2009 10:17 AM Gonzalo Garcia-Perate said...
> Emile, Kent thank you both for your reply, after sending my previous
> email I realised that it wasn't working as expected in all cases.
> 
> this does work:
> 
> def within_range_final(self, n, n2, threshold=5):
>      return n in range(n2-threshold, n2+threshold+1)


To explain why we've tended to suggest using int and minval<val<maxval 
as tests and avoid the range inclusion test, consider the following 
timeit results:


C:\Python26\Lib>python timeit.py "6 in range(10)"
1000000 loops, best of 3: 1.22 usec per loop

C:\Python26\Lib>python timeit.py "0< 6 < 10 and 6==int(6)"
1000000 loops, best of 3: 0.676 usec per loop

C:\Python26\Lib>python timeit.py "0< 6 < 10 and isinstance(6,int)"
1000000 loops, best of 3: 0.526 usec per loop

Granted, it only takes twice as long, and it's certainly not a long 
time, but the point is that there is a time penalty you're paying to 
construct the range object, then pass it one at a time to test for 
inclusion, only to immediately have the construct pass out of scope and 
be garbage collected.  Those who've worked with python over time tend to 
favor constructs and idioms that perform better as a matter of course.

Further, as the threshold range increases, the difference becomes more 
noticeable.  For example, testing with 100 and 1000 :

C:\Python26\Lib>python timeit.py "0< 6 < 100 and isinstance(6,int)"
1000000 loops, best of 3: 0.532 usec per loop

C:\Python26\Lib>python timeit.py "6 in range(100)"
100000 loops, best of 3: 2.52 usec per loop

C:\Python26\Lib>python timeit.py "6 in range(1000)"
100000 loops, best of 3: 19.1 usec per loop

C:\Python26\Lib>python timeit.py "0< 6 < 1000 and isinstance(6,int)"
1000000 loops, best of 3: 0.527 usec per loop

Emile



More information about the Tutor mailing list