我的代码导致内核重新启动。为什么内核会重新启动?

3
我编写了这段 Python 代码,并获得了意外的输出。输出是一串零,然后显示“重新启动内核”。为什么内核会重新启动?
def countdown(n):
    for n in range(0,5):
        print(n)
        countdown(n-1)
countdown(2)

另一方面,我尝试使用if,没有问题:

def countdown(n):
    if n == 0:
        print("blast of")
    else:
        print(n)
        countdown(n-1)
countdown(5)

那么为什么它不能与 for 一起使用呢?

2
你没有收到递归错误吗? - Fiddling Bits
1
你的函数无限制地调用自身。如果你想要一个递归函数,你需要一个基本情况来限制堆栈使用。 - quamrana
1
另外,在for循环中,您正在遮蔽n参数。 - ljmc
好的,与我的通常做法相反,我要求您也发布“我尝试使用'if'”代码,以便我们进行比较。 - quamrana
如果你在 Jupyter notebook 上运行这段代码,你可能会错过递归错误。尝试将代码写入一个常规的 .py 文件中,你应该能看到实际的错误信息。 - Kraigolas
3个回答

2
>    def countdown(n):
>        for n in range(0,5):
>            print(n)
>            countdown(n-1)
>    countdown(2)

在您上面的代码中,每个函数调用将递归调用5次。因此第一次调用是5,第二次调用将有25个调用,第三次调用125个调用,递归调用呈指数级增长,导致内核重新启动。
如果使用递归函数,必须有一个退出条件。有几种方法可以实现您的目标:
(1)带有if条件退出的递归(这是您成功的代码)
def countdown(n):
    if n == 0:
        print("blast off!")
    else:
        print(n)
        countdown(n-1)
countdown(5)

(2) 带有 while 条件退出的递归

def countdown(n):
    while n != 0:
        print(n)
        countdown(n-1)
        return
    print("blast off!")
countdown(5)

(3) for循环(无需递归)

def countdown(n):
    for i in range(n, 0, -1):
        print(i)
    print("blast off!")
countdown(5)

输出:

5
4
3
2
1
blast off!

1

使用递归的if版本是递归的正确形式。

使用for循环时,不需要递归函数,只需从n到0迭代,完成后打印您的发射倒计时。

def countdown(n):
    for in range(n,0,-1):
        print(n)
    else:
        print("blast off")

注意:这里使用了for/else结构,这意味着当for循环完全执行而没有break时,将执行else块。

countdown(5)的输出结果为

5
4
3
2
1
blast off

1

您所发布的代码:

def countdown(n):
    if n == 0:
        print("blast of")
    else:
        print(n)
        countdown(n-1)
countdown(5)

这是一个递归函数,因为它有一个基本情况(if n == 0:)。

由于递归,此代码内置了循环:countdown(n-1)

如果您想要一个for循环,那么您真的不需要递归。


我该如何为for循环做这件事? - Nidhi Kushwaha
@ljmc用for循环版本回答了。 - quamrana

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接