2

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

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()如果它试图解释那个函数,那么现在它怎么可能是一个浮点函数呢?是否有一种两循环程序来评估和解释函数?或者我在这里有什么问题吗?

4

3 回答 3

4

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

于 2014-05-13T17:57:34.377 回答
0

您刚刚偶然发现了recursion

递归函数在编程中很常见。考虑以下用于计算n斐波那契数的(朴素)函数:

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

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

于 2014-05-13T18:01:50.220 回答
0

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

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

fun2 = fun1

def fun1(x):
    print x

fun2(3)

在这里,我们使用fun1()对自身的明显递归调用来定义。然而,在重新fun1()定义后,函数的第一个定义中的调用现在完全引用了一个不同的函数。

于 2014-05-13T18:07:43.233 回答