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

编程新手:尝试理解记忆化示例与Python 3的关系,python,python-3.x,Python,Python 3.x,正如我所说,我是编程新手,我喜欢在youtube上观看CS Dojo作为我的学习材料(以及其他教程)。他使用了一个记忆化的例子,但似乎不适用于Python3。试图理解如何使用正确的语法以及它是如何工作的。下面是他使用记忆法查找斐波那契序列中的数字的示例 def fib(n, memo): if memo[n] != null: return memo[n] if n == 1 or n == 2: result = 1 else:

正如我所说,我是编程新手,我喜欢在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

他也没有说明如何为此打印结果,因此这将是一个很大的帮助。

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

所以,这里的简单答案是:不要再看那个系列了。它不是在教你Python


第一个问题是Python中没有名为
null
的内置值

有一个名为
None
的值

或者,也许,在他的代码的其他地方,他做了
null=object()
来创建一个与
None
不同的唯一哨兵值,以便在
None
是合法值时使用?但在这里这样做真的没有意义;此函数只能返回
int

此外,您几乎不应该使用
!=无
;使用
不是无
。出于同样的原因,如果您创建了一个新的自定义哨兵,如
null=object()
,您还需要检查
是否不为null


第二个问题是Python
dict
s在查找不存在的值时不返回
None
null
或任何其他值;它们会引发一个
KeyError
异常

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

在这里正确的做法是
,除了keyrerror:
,或者
如果memo.get(n)不是None:


当我们这样做的时候:记忆一个函数是可变默认习惯用法的范例。它在官方Python常见问题解答中,我认为甚至在教程中也是如此。当不需要时,为什么要强迫用户构建一个
备忘录(并尝试找出它应该是什么…)


因此:


当然,编写这篇文章的真正惯用方法是使用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(fib(123))
尽管不要尝试以下任何一项:

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

…除非您想查看Python中的
RecursionError
是什么样子。

在Python中,无论是Python 3、Python 2还是Python 0.9,都没有名为
null
的内置值。也许他定义了
null=object()
或者代码中的其他地方。如果不是,那就是坏代码。他可能是指没有。但即便如此,除非
memo
是一个
defaultdict(lambda:None)
,否则它仍然是坏的,因为
memo[n]
不会是
None
,它将是一个
KeyError
。有很多在线工作代码的例子——斐波那契函数是记忆的经典案例。我想其中一个对你有用。StackOverflow不是设计、编码、研究或教程服务。当您有特定问题时,请重新发布。如果备忘录[n]!=如果备忘录中有n,则为空
,带有
。我相信他或她只是提供了一个一般的说法:如果在memo表中查找参数n,则返回一个有效值。请注意,
memo
必须是某种支持某种形式的索引的数据结构。@Abdou本课程的目的大概是教你如何用Python编程,而不是编写看起来像Python但不是的伪代码。我怀疑这个问题的OP是唯一一个被它弄糊涂的人。@abarnert我想我做出了这个假设,因为OP说他们喜欢在youtube上观看CS Dojo作为我的学习材料。
print(fib(0))
print(fib(1.5))
print(fib(1001))