简体   繁体   English

Python中的递归函数悖论..怎么解释?

[英]recursive function paradox in Python.. how can it be explained?

I made a very simple function that takes a list of numbers and returns a list of numbers rounded by some digits: 我做了一个非常简单的函数,该函数接受一个数字列表并返回一个由一些数字四舍五入的数字列表:

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

However, I mistakenly put the function itself in the code instead of the built-in round() (as in the example below): 但是,我错误地将函数本身放在代码中,而不是内置的round() (如下例所示):

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

and got this output: 并得到以下输出:

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

The question is: how does the interpreter know that it had to apply the function rounded() while evaluating the function rounded() itself? 问题是:解释器如何知道在评估函数rounded()本身时必须应用rounded()函数? How can it anyway now that rounded() is a function taking floats if it is attempting to interpret that very function? 现在,如果rounded()是试图解释该函数的函数,那怎么可能呢? Is there a sort of two cycle procedure to evaluate & interpret functions? 是否存在一种评估和解释功能的两个周期过程? Or am I getting something wrong here? 还是我在这里出了点问题?

The function is an object. 该函数是一个对象。 It is created at definition, not when it is called, so if Python didn't know how to use it, it would've raised an error before any calling was done. 它是在定义时创建的,而不是在调用时创建的,因此,如果Python不知道如何使用它,它将在进行任何调用之前引发错误。
However, you called it with a list. 但是,您使用列表进行了调用。 During the iteration, the function is called recursively with the first item of the list - presumably, a float. 在迭代过程中,使用列表的第一项(大概是浮点数)递归调用该函数。 With this float as argument, for i in lista: doesn't make sense anymore, and you have the error. 使用此float作为参数, for i in lista:不再有意义,并且出现错误。

You've just stumbled upon recursion . 您刚刚偶然发现了递归

Recursive functions are very common in programming. 递归函数在编程中非常常见。 Consider the following (naive) function for calculating the n th fibbonacci number: 考虑以下(幼稚的)函数来计算第n个斐波那契数:

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

The function knows that it calls itself, because the function definition is noted as soon as the interpreter reaches fib(x): . 该函数知道它自己进行调用,因为解释器在到达fib(x):便立即记录了函数定义。 From that point on, fib is defined. 从那时起,就定义了fib For python in particular, since it's a dynamically typed language, there's no difference if you call the function with a integer, a string or a float - all it matters is that the function takes exactly one argument. 特别是对于python,因为它是一种动态类型的语言,所以用整数,字符串或浮点数调用函数没有什么区别-重要的是该函数只接受一个参数。

There are indeed two processes occurring here. 确实有两个过程在这里发生。 The function is compiled as it's encountered in the source text, then a call is made to it afterward. 该函数在源文本中遇到时进行编译,然后对其进行调用。 The body of the function includes a call to rounded , but that's actually kept track of as the name of the function. 该函数的主体包括对rounded的调用,但是实际上一直在跟踪该函数的名称。 Check this out: 看一下这个:

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

fun2 = fun1

def fun1(x):
    print x

fun2(3)

Here we're defining fun1() with an apparently recursive call to itself. 在这里,我们定义了fun1()并对其进行了明显的递归调用。 However, after redefining fun1() , the call in the first definition of the function now refers to a different function entirely. 但是,在重新定义fun1() ,该函数的第一个定义中的调用现在完全引用了另一个函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM