Python - does range() mutate variable values while in recursion?
<p>While working on understanding string permutations and its implementation in python (regarding to <a href="http://stackoverflow.com/a/20955291/1055601">this post</a>) I stumbled upon something in a <code>for</code> loop using <code>range()</code> I just don't understand.</p>

<p>Take the following code:</p>

<pre><code>def recursion(step=0):
    print "Step I: {}".format(step)
    for i in range(step, 2):
        print "Step II: {}".format(step)
        print "Value i: {}".format(i)

        print "Call recursion"
        print "\n-----------------\n"

        recursion(step + 1)

recursion()
</code></pre>

<p>That gives the following output:</p>

<pre><code>root@host:~# python range_test.py

Step I: 0
Step II: 0
Value i: 0
Call recursion

-----------------

Step I: 1
Step II: 1
Value i: 1
Call recursion

-----------------

Step I: 2
Step II: 0 &lt;---- WHAT THE HECK?
Value i: 1
Call recursion

-----------------

Step I: 1
Step II: 1
Value i: 1
Call recursion

-----------------

Step I: 2
root@host:~#
</code></pre>

<p>As you can see the variable <code>step</code> gets a new value after a certain <code>for</code> loop run using <code>range()</code> - see the <code>WHAT THE HECK</code> mark.</p>

<p>Any ideas to lift the mist?</p>

<p>Your conclusion is <strong>incorrect</strong>. <code>step</code> value does not change by using <code>range</code>.
This can be verified as:</p>

<pre><code>def no_recursion(step=0):
    print "Step I: {}".format(step)
    for i in range(step, 2):
        print "Step II: {}".format(step)
        print "Value i: {}".format(i)

no_recursion(step=2)
</code></pre>

<p>which produces the output:</p>

<pre><code> Step I: 2
</code></pre>

<p>which is expected since <code>range(2,2)</code> returns <code>[]</code>.</p>

<p>The illusion that <code>step</code> changes its value to 0 comes since the function <code>recursion</code> (called with <code>step=2</code>) returns after it prints <code>Step I: 2</code>, then control is returned to function <code>recursion</code> (called with <code>step=1</code>) which immediately returns since its <code>for loop</code> has terminated, and then control is returned to <code>recursion</code> (called with <code>step=0</code>) which continues since it has 1 iteration left, and that prints <code>Step II: 0</code> to console which is no surprise. This can be simpler to observe if we modify the code a little bit (by adding function entry and exit logging) and observe the output:</p>

<pre><code>def recursion(step=0):
    print "recursion called with [step = {}]".format(step) # add entry logging
    print "Step I: {}".format(step)
    for i in range(step, 2):
        print "Step II: {}".format(step)
        print "Value i: {}".format(i)

        print "Call recursion"
        print "\n-----------------\n"

        recursion(step + 1)
    print "--&gt; returned recursion [step = {}]".format(step) # add exit logging 

recursion() 
</code></pre>

<p>the output produced by this code is :</p>

<pre><code>recursion called with [step = 0]
Step I: 0
Step II: 0
Value i: 0
Call recursion

-----------------

recursion called with [step = 1]
Step I: 1
Step II: 1
Value i: 1
Call recursion

-----------------

recursion called with [step = 2]
Step I: 2
--&gt; returned recursion [step = 2]
--&gt; returned recursion [step = 1]
Step II: 0
Value i: 1
Call recursion

-----------------

recursion called with [step = 1]
Step I: 1
Step II: 1
Value i: 1
Call recursion

-----------------

recursion called with [step = 2]
Step I: 2
--&gt; returned recursion [step = 2]
--&gt; returned recursion [step = 1]
--&gt; returned recursion [step = 0]
</code></pre>

<p>where we can clearly see that order in which recursion unfolds and observer that value of <code>step</code> is consistent in each step.</p>

python recursion