Python递归函数 - 引用当前和以前的参数

时间:2018-06-13 16:09:43

标签: python recursion

我将新参数(previous_high,previous_score)传递给announce_highest,那么如何引用旧参数进行比较呢?

很抱歉,如果这个问题非常基础,仍然可以了解递归函数的工作原理!

var movieDb = [ { title:"gujja",
                  rating:5,
                  haveWatched:true, },
                { title:"la",
                  rating:5,
                  haveWatched:false,}];
movieDb.forEach(function(movie){
        var result = "you have ";
       if (movie.havewatched){
          result += "watched ";
}else {
          result += "not seen ";
}
result += `${movie.title} -`
result += `${movie.rating}`
console.log(result);
});

1 个答案:

答案 0 :(得分:1)

这里描述了

The problem from CS61A

你的第一个错误就是试图让它成为一个递归函数。他们要求你编写一个更高阶的函数(高阶函数是一个函数,它将函数作为参数或返回函数作为其输出的一部分;在我们的例子中,我们想要一个返回函数的函数)。

具体来说,我们希望announce_highest返回closure。闭包基本上是一个函数(需要输入,处理它并返回输出的东西),它还具有自己定义的内部变量的本地环境,它从定义闭包的环境继承。

你的闭包应该有三个内部变量:

  • who,玩家在分数增加时(0或1)宣布
  • previous_high您追踪的玩家所拥有的最高得分
  • previous_score您追踪的玩家的得分

这个闭包有两个参数current_player0_scorecurrent_player1_score

没有为你做功课,这里有两个类似的高阶函数的例子,它返回一个闭包。首先,我创建了一个my_counter_factory闭包创建者。这是一个函数,当被调用时会创建一个计数器,该计数器在计数为偶数或奇数时通知(取决于最初创建时变量announce_if_even_countannounce_if_odd_count变量的值)。

def my_counter_factory(initial_count=0, announce_if_even_count=True, announce_if_odd_count=False):
    count = initial_count
    def counter(increment_by):
        new_count = count + increment_by
        if announce_if_even_count and new_count % 2 == 0:
            print("Count is even %s" % new_count)
        if announce_if_odd_count and new_count % 2 == 1:
            print("Count is odd %s" % new_count)
        return my_counter_factory(new_count, announce_if_even_count, announce_if_odd_count)
    return counter

当运行时将起作用:

 >>> c0 = my_counter_factory(10, True, True) # count = 10, announce count if even or odd

 >>> c1 = c0(5) # announces 15 creates new counter `c1` with count of 15 
                # note count of c0 is still 10.
 Count is odd 15

 >>> c2 = c1(3) # count is 18 (stored in new closure c2) by adding 3 to c1 count.  
 Count is even 18

 # See value of closures by incrementing 0 to them:
 >>> ignore = c0(0)
 Count is even 10
 >>> ignore = c1(0)
 Count is odd 15
 >>> ignore = c2(0)
 Count is even 18

注意每次调用此闭包时,它都会返回一个全新的闭包(具有自己的新环境)。一个同样有效的选择(行为略有不同)是每次都不创建新的闭包,但不断返回相同的闭包。

def my_counter_factory(initial_count=0, announce_if_even_count=True, announce_if_odd_count=False):
    count = initial_count
    def counter(increment_by):
        nonlocal count  # more on this below.
        count += increment_by
        if announce_if_even_count and count % 2 == 0:
            print("Count is even %s" % count)
        if announce_if_odd_count and count % 2 == 1:
            print("Count is odd %s" % count)
        return counter # This returns back same closure each time.
    return counter

这将作为:

 >>> c0 = my_counter_factory(10, True, True) # count = 10, announce count if even or odd

 >>> c1 = c0(5) # adds 5 to count of c0 closure (was 10, now 15) announces 15 
 # c1 is a reference to the same closure as c0 with the same count                  
 Count is odd 15

 >>> c2 = c1(3) # adds 3 to count of c1 closure (now at 18), 
 Count is even 18

 # See value of closures by incrementing 0 to them:
 >>> ignore = c0(0)
 Count is even 18
 >>> ignore = c1(0)
 Count is even 18
 >>> ignore = c2(0)
 Count is even 18

 >>> c0 == c1 == c2  
 True
 # Note in this second example all three closures are identical, 
 # because the closure merely returns a reference to itself when called

 # Granted you could create a brand new closure
 >>> new_c = my_counter_factory(0, True, False) 
 # This one starts with a count of 0 and only announces when it's even
 >>> new_c2 = new_c(5)

最后注意:您可能想知道为什么在第二个示例中,我们需要行nonlocal count(但我们在第一个示例中并不需要它),如果您将其取出,则会出现错误{ {1}}。 python中的闭包允许引用其定义的环境中的变量(不使用python3中引入的local variable 'count' referenced before assignment关键字),只要它们不重新赋值值给它们。基本上当python试图解释你的函数时,它区分局部变量(在函数中定义)和在别处定义的变量。例如:

nonlocal

需要注意的重要一点是,我们调用了一个函数>>> def print_0_to_4(): ... for i in range(5): ... print(i, end=", ") ... print("") ... >>> i=-1 >>> print_0_to_4() 0, 1, 2, 3, 4, >>> i -1 ,该函数分配给变量print_0_to_4,使i成为局部变量。对函数中局部变量的更改不会修改外部环境中具有相同名称的变量的值。 (否则编程会非常困难,因为我们需要知道我们调用的每个函数的内部变量的名称,因为担心在调用函数时无意中修改了我们的变量。)

另请注意,如果您没有为函数中的变量赋值/修改,则可以引用另一个范围中定义的变量(不需要i关键字)。

nonlocal