编程新手:尝试理解记忆化示例与python3的关系

2024-05-14 11:22:56 发布

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

正如我所说,我是编程新手,我喜欢在youtube上观看CS Dojo作为我的学习资料(以及其他教程)。他使用了一个记忆化的例子,但似乎不适用于python3。试图理解如何使用正确的语法以及它是如何工作的。下面是他使用记忆法来寻找斐波那契数列中的数字的例子。。。你知道吗

def fib(n, memo):
    if memo[n] != null:
        return memo[n]
    if n == 1 or n == 2:
        result = 1
    else: 
        result = fib(n-1) + fib(n-2)
    memo[n] = result
    return result

他也没有展示如何打印这个结果,所以这也将是一个很大的帮助。你知道吗


Tags: 记忆returnifyoutube编程教程resultcs
1条回答
网友
1楼 · 发布于 2024-05-14 11:22:56

这段代码被分解为Python。不仅仅是Python3;它在Python2或Python0.9中被破坏了。看起来有人不知道Python试图从JavaScript转换一些东西,但甚至没有测试它。你知道吗

所以,简单的回答是:别再看那个系列了。这不是教你Python。你知道吗


第一个问题是Python中没有名为null的内置值。你知道吗

有一个叫做None的值。你知道吗

或者,在他的代码中的其他地方,他创建了一个不同于None的独特的sentinel值,当None是合法值时使用?但是在这里这样做是没有意义的;这个函数只能返回一个int。你知道吗

而且,您几乎不应该将!= NoneNone一起使用;使用is not None。出于同样的原因,如果您创建了一个新的定制sentinel,比如null = object(),那么您还需要检查is not null。你知道吗


第二个问题是,当您查找不存在的值时,Python dict不会返回Nonenull或其他任何东西;它们会引发KeyError异常。你知道吗

也许他定义了memo = collections.defaultdict(lambda: null)并将其传递给函数?但如果是这样的话,这里就没有理由这么做;这只会让代码变得更加复杂和混乱,毫无益处。你知道吗

正确的做法是except KeyError:,或if n in memo,或if memo.get(n) is not None:。你知道吗


当我们这样做的时候:记忆一个函数是可变默认习惯用法的范例。它在官方的Python FAQ中,我认为甚至在教程中也是如此。为什么要强迫用户构造一个memo(并试图找出它应该是什么…)而不是必要的呢?你知道吗


所以:

def fib(n, *, memo={}):
    if n in memo:
        return memo[n]
    if n == 1 or n == 2:
        result = 1
    else: 
        result = fib(n-1) + fib(n-2)
    memo[n] = result
    return result

当然,编写这篇文章的惯用方法是使用Python自带的电池:

@functools.lru_cache(maxsize=None):
def fib(n):
    if n == 1 or n == 2:
        return 1
    return fib(n-1) + fib(n-2)

教人们如何手动操作是一件好事,但你也应该向他们展示,一旦他们了解了轮子是如何工作的,就不要重新发明轮子。你知道吗


至于如何打印结果,这很简单:它与任何其他函数调用相同,它返回一个值,您可以print该值:

print(fib(123))

尽管不要尝试以下任何一种方法:

print(fib(0))
print(fib(1.5))
print(fib(1001))

…除非您想看看RecursionError在Python中是什么样子。你知道吗

相关问题 更多 >

    热门问题