Python - 在递归时range()是否会改变变量值?

时间:2016-09-07 06:06:12

标签: python recursion

在理解字符串排列及其在python中的实现(关于this post)时,我偶然发现使用for range()循环中的某些内容我只是不明白。

请使用以下代码:

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()

这给出了以下输出:

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 <---- WHAT THE HECK?
Value i: 1
Call recursion

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

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

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

Step I: 2
root@host:~#

正如您所看到的,变量step在使用for运行某个range()循环后获得了新值 - 请参阅WHAT THE HECK标记。

任何解除雾气的想法?

1 个答案:

答案 0 :(得分:1)

您的结论不正确。使用step不会更改range值。 这可以验证为:

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)

产生输出:

 Step I: 2

这是预期的,因为range(2,2)会返回[]

step将其值更改为0的错觉来自函数recursion(使用step=2调用)在打印Step I: 2后返回,然后控制返回到函数自recursion终止后立即返回的step=1(使用for loop调用),然后控件返回recursion(使用step=0调用)它剩下1次迭代,并将Step II: 0打印到控制台,这并不奇怪。如果我们稍微修改代码(通过添加函数入口和退出日志记录)并观察输出,这可以更容易观察:

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 "--> returned recursion [step = {}]".format(step) # add exit logging 

recursion() 

此代码生成的输出是:

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
--> returned recursion [step = 2]
--> 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
--> returned recursion [step = 2]
--> returned recursion [step = 1]
--> returned recursion [step = 0]

我们可以清楚地看到递归的顺序,并观察step的值在每一步中都是一致的。