理解递归函数调用

时间:2016-03-24 18:41:29

标签: python function python-3.x recursion

请考虑以下代码:

<Style x:Key="CircleButtonStyle" TargetType="{x:Type Button}">
    <!-- ... -->
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <Rectangle
                    Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}, Path=Width, Converter={StaticResource ArithmeticConverter}}"
                    Height="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}, Path=Height, Converter={StaticResource ArithmeticConverter}}"
                    Fill="White"
                    >
                    <Rectangle.OpacityMask>
                        <VisualBrush Visual="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}, Path=Content}"/>
                    </Rectangle.OpacityMask>
                </Rectangle>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

<!-- ... -->

<Button 
    Style="{DynamicResource CircleButtonStyle}" 
    Command="{Binding Remove}" 
    ToolTip="Remove product filter." 
    Content="{DynamicResource appbar_music}"
    />

这里Python检查n是否小于或等于0,它发现这是 False 所以它打印'mah'并用n-1调用相同的函数,直到n等于0 ,所以'mah'打印3次。

但请考虑这个被操纵的代码:

def print_mah(n):
    if n <= 0:
        return
    else:
        print('mah') 
        print_mah(n-1) 

print_mah(3)

Python检查n是否小于或等于0,它发现这是 False 所以再次使用n-1调用相同的函数,并且'mah'也被打印3次。

我的问题是,为什么'mah'不会只打印一次,换句话说为什么print_mah不会被调用n = 2,然后Python发现条件是 False ,所以它用n = 1调用它,并发现条件为 False ,所以用n == 0调用它,并发现条件为 True ,所以函数返回,然后打印'mah',只打印一次。

6 个答案:

答案 0 :(得分:1)

要理解不同可能这会有所帮助。

算法1

def print_n(n):
    if n <= 0:
        return
    else:
        print_n(n-1)
        print(n)

算法2

def print_n(n):
    if n <= 0:
        return
    else:
        print(n)
        print_n(n-1)

这些算法应该提供不同的结果,这可能是进一步研究的良好起点。

一些帮助

如果在另一个函数(f1)中调用函数(f2),则当前函数(f1)将一直等到被调函数(f2)结束。

一些研究关键词

  • 函数调用

答案 1 :(得分:1)

  

Python发现条件为False,因此它用n = 1调用它,并且发现条件为False,因此它用n == 0调用它,并发现条件为True,因此函数返回< / p>

这实际上是第二个版本的确切执行路径。但是,你可能没有看到,当函数返回时,它会在递归调用返回之后退回,就像任何其他方法调用一样。

因此,当n==1并使用n==0进行递归时,会返回并首次打印mah,然后返回mah时{ {1}},然后返回,n==2打印第三次也是最后一次。

答案 2 :(得分:1)

两个函数都会打印.grp-container{ width:30%; border:1px solid #000; height:70x; } .icon{ width:40px; height:10px; background:red; float:left; margin:3px; } .clear{ clear:both; } 三次,因为在递归调用后你没有返回任何内容。当您在其自身内部调用函数时,您应该处理停止条件(您已经在第一个if条件中执行过),之后它将不会退出程序,因为递归调用会构建一堆操作。在最后一个操作停止(返回一些东西)之后,它将在返回的路上开始在递归调用之下编译函数的其余部分,直到到达函数的末尾。

答案 3 :(得分:1)

return不会打破整个调用堆栈,只会打破当前的函数调用。在这种情况下:

def print_mah(n):
  if n <= 0:
      return
  else: 
      print_mah(n-1)
      print('mah')

print_mah(3)
在返回0之前,

print_mah被调用三次。您可以将其视为嵌套逻辑,如下所示:

def print_mah(n):
  if n <= 0:
      return
  else: 
      print_mah(n-1) # Replace this line with new call
      print('mah')

我们只是在评论的else语句中再次调用该函数。

def print_mah(n):
  if n <= 0:
      #return
  else:
      n = n-1
      if n <= 0:
          #return
      else: 
          print_mah(n-1)
          print('mah')
      print('mah')

你可以看到print('mah')在底部按顺序显示,正如它所写的那样,当函数从调用堆栈中回溯时,它将按顺序打印。

答案 4 :(得分:1)

这是第二个程序正在做的“跟踪”:

print_mah(3) ->
  print_mah(2) ->
    print_mah(1) ->
      print_mah(0) ->
        # Does nothing, essentially.
        <-
      # print_mah(1) continues running.
      print('mah')  # The last thing that print_mah(1) does.
      <-
    # print_mah(2) continues running.
    print('mah')
    <-
  # print_mah(3) continues running.
  print('mah')
  <-

我们在这里看到的是print('mah')出现三次(因此,'mah'会被打印三次)。

答案 5 :(得分:1)

  

我的问题是为什么&#39; mah&#39;没有打印一次,换句话说,为什么print_mah没有被n = 2调用,然后Python发现条件为False,所以它用n = 1调用它,并发现条件为False ,所以它用n == 0来调用它,并发现条件为True,所以函数返回,之后&#39; mah&#39;只打印一次。

该函数仅返回最内部函数。在调用else并实际打印之后,使用print_mah条件的两个功能级别将继续执行。为简洁起见,这是print_mah(2)的逐行演练。

print_mah(2)
# Enter print_mah - Level 1

    if n <= 0: # n = 2
        # ...
    # False, continue to else

    else: 
        print_mah(n-1)  # n = 2
    # Enter print_mah - Level 2

        if n <= 0: # n = 1
        # ...
        # False, continue to else

        else: 
            print_mah(n-1)  # n = 1
        # Enter print_mah - Level 3

            if n <= 0: # n = 0
                return
            # Return None to print_mah - Level 2

        print('mah')
        # Function is complete, return None to print_mah - Level 1

    print('mah')
    # Function is complete, return None to the execution scope