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

2024-05-16 00:58:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我传递新的参数(previous_high,previous_score)来宣布_最高,那么我如何引用旧的参数来进行比较呢?在

抱歉,如果这个问题很基本,还在学习递归函数的工作原理!在


def announce_highest(who, previous_high=0, previous_score=0):
    """Return a commentary function that announces when WHO's score
    increases by more than ever before in the game.

    >>> f0 = announce_highest(1) # Only announce Player 1 score gains
    >>> f1 = f0(11, 0)
    >>> f2 = f1(11, 1)
    1 point! That's the biggest gain yet for Player 1
    >>> f3 = f2(20, 1)
    >>> f4 = f3(5, 20) # Player 1 gets 4 points, then Swine Swap applies
    19 points! That's the biggest gain yet for Player 1
    >>> f5 = f4(20, 40) # Player 0 gets 35 points, then Swine Swap applies
    20 points! That's the biggest gain yet for Player 1
    >>> f6 = f5(20, 55) # Player 1 gets 15 points; not enough for a new high
    """
    assert who == 0 or who == 1, 'The who argument should indicate a player.'
    # BEGIN PROBLEM 7
    gain = #compare previous argument to current argument
    if gain > previous_high:
        if gain == 1:
            print(gain, 'point! That\'s the biggest gain yet for Player', who)
        else: 
            print(gain, 'points! That\'s the biggest gain yet for Player', who)

    return announce_highest(some args)
    # END PROBLEM 7

Tags: theforthatpointsyetscoregainplayer
1条回答
网友
1楼 · 发布于 2024-05-16 00:58:34

此处描述The problem from CS61A。在

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

具体来说,我们希望announce_highest返回一个closure。基本上,它继承了一个被定义的环境的闭包,它有一个定义了的内部变量的闭包。在

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

  • who,当他们的分数增加时宣布(0或1)
  • previous_high你跟踪的玩家的最高分数
  • previous_score上次跟踪的玩家的分数

这个闭包接受两个参数current_player0_score和{}。在

下面是两个类似的高阶函数的示例,它返回一个闭包。首先,我创建一个my_counter_factory闭包创建者。它是一个函数,当被调用时,它会创建一个计数器来宣布计数是偶数还是奇数(取决于变量announce_if_even_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

当运行时将作为:

^{pr2}$

注意每次调用这个闭包时,它都会返回一个全新的闭包(有它自己的新环境)。同样有效的选择(行为稍有不同)是不每次都创建新的闭包,而是继续返回相同的闭包。在

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(但在第一个示例中我们不需要它),如果您去掉它,您将得到一个错误消息local variable 'count' referenced before assignment。python中的闭包可以从定义它的环境中引用变量(不使用python3中引入的nonlocal关键字),只要它们不向它们重新分配值。当python函数中定义的变量(基本上是在其他地方定义的)试图区分函数中定义的局部变量。例如:

>>> 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关键字)。在

>>> i = -1
>>> def print_i_from_outer_scope():
...     print(i)
... 
>>> print_i_from_outer_scope()
-1

相关问题 更多 >