【问题标题】:recursive function paradox in Python.. how can it be explained?Python中的递归函数悖论..如何解释?
【发布时间】:2014-07-01 13:04:41
【问题描述】:

我做了一个非常简单的函数,它接受一个数字列表并返回一个由一些数字四舍五入的数字列表:

def rounded(lista, digits = 3):
    neulist = []
    for i in lista:
        neulist.append(round(i, digits))
    return neulist

但是,我错误地将函数本身放入了代码中,而不是内置的round()(如下例所示):

def rounded(lista, digits = 3):
    neulist = []
    for i in lista:
        neulist.append(rounded(i, digits))
    return neulist

得到这个输出:

Traceback (most recent call last):
  File "<pyshell#286>", line 1, in <module>
    rounded(a)
  File "<pyshell#284>", line 4, in rounded
    neulist.append(rounded(i, digits))
  File "<pyshell#284>", line 3, in rounded
    for i in lista:
TypeError: 'float' object is not iterable

问题是:解释器如何知道它必须在评估函数 rounded() 本身时应用函数 rounded()?既然rounded() 是一个浮点函数,如果它试图解释那个函数,它怎么可能呢?是否有一种两循环程序来评估和解释函数?还是我这里有什么问题?

【问题讨论】:

  • 跑题了,顺便说一句:rounded = lambda l: map(lambda x: round(x, 1), l)

标签: python function interpreter evaluation-function


【解决方案1】:

函数是一个对象。它是在定义时创建的,而不是在调用时创建的,所以如果 Python 不知道如何使用它,它会在任何调用完成之前引发错误。
但是,您使用列表调用它。在迭代期间,使用列表的第一项递归调用该函数 - 大概是一个浮点数。使用此浮点数作为参数,for i in lista: 不再有意义,并且您遇到了错误。

【讨论】:

  • 在我认为正确的答案中添加更多内容:您调用了rounded(a_list),它在for 循环内从该列表中提取第一项i,然后致电rounded(i, digits)。由于i 是一个浮点数,当您在第二次rounded 调用中尝试执行for (new_i) in i 时会遇到错误。
  • 你是对的,当我调用函数时提示错误,现在当我实例化它时,所以我想这只是我的错觉。感谢您快速明确的回答!
【解决方案2】:

你刚刚偶然发现了recursion

递归函数在编程中很常见。考虑以下(简单)函数来计算nth 斐波那契数:

def fib(x):
    if x<=2:
        return 1
    else:
        return fib(x-1)+fib(x-2)

函数知道它调用了自己,因为函数定义在解释器到达fib(x): 时就被记录下来。从那时起,fib 被定义。特别是对于 python,因为它是一种动态类型的语言,所以使用整数、字符串或浮点数调用函数没有区别——重要的是函数只接受一个参数。

【讨论】:

    【解决方案3】:

    这里确实发生了两个过程。该函数在源文本中遇到时被编译,然后调用它。函数的主体包括对rounded 的调用,但实际上它作为函数的名称被跟踪。看看这个:

    def fun1(x):
        if x == 0:
            print x
        else:
            fun1(x-1)
    
    fun2 = fun1
    
    def fun1(x):
        print x
    
    fun2(3)
    

    在这里,我们定义fun1(),显然是对其自身进行递归调用。但是,在重新定义 fun1() 之后,函数的第一个定义中的调用现在完全引用了一个不同的函数。

    【讨论】:

      猜你喜欢
      • 2012-05-20
      • 1970-01-01
      • 2022-06-23
      • 1970-01-01
      • 2021-07-15
      • 1970-01-01
      • 2016-05-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多