[Tutor] range efficiency

Steven D'Aprano steve at pearwood.info
Sat May 11 08:27:40 CEST 2013


On 11/05/13 07:19, Jim Mooney wrote:
> If I'm using a variable-dependent range in a for loop, is Python smart
> enough to figure the variable once so I don't have to hoist it up?
>
> That is for c in range(0,x+2), is x+2 figured once or every time
> through the loop? I'm assuming it's once but I like to verify.

Yes, it is calculated once.

Remember that range() is not a syntax feature, it is a function that returns an object. Since it is a function, its argument must be figured *before* the function is called, and once the range function has returned, it is done.

So you can write something like this in Python 3:


py> x = 3
py> values = range(0, x+2)
py> print(values)
range(0, 5)
py> for c in values:
...     print(c)
...
0
1
2
3
4


Python 2 is the same, except that instead of getting that mysterious "range(0, 5)" line printed, you get an actual list of values [0, 1, 2, 3, 4].


By the way, you don't need to include the starting value of 0 for range. range(0, x+2) is exactly the same as range(x+2).



Here are a couple of "monkey-patching" tricks for testing things like this. Let's patch the range function to display when it is called, and make a chatty little object that prints when it is added to.

=== cut ===

saved_range = range
def range(*args):
     print("calling range function")
     return saved_range(*args)

class Chatty(int):
     def __add__(self, other):
         print("adding %s and %s" % (self, other))
         return int.__add__(self, other)

x = Chatty(3)
for c in range(x+2):
     print(c)

=== cut ===


If you copy the code between the "cut" lines, and paste into an interactive interpreter, you will see what Python does when executing this sort of for-loop.



-- 
Steven


More information about the Tutor mailing list