在Python如何打印100以内的斐波那契数列?

来源:MySQL教程作者:桃乃木香奈头衔:网络博主
导读:本期聚焦于桃乃木香奈创作的《在Python如何打印100以内的斐波那契数列?》,敬请观看详情。为什么按照普通递推写法打印斐波那契数列时,终端里常会多出一个144这样的越界值?问题通常出在循环判断与更新顺序没有被拆开理解。本文围绕Python打印100以内斐波那契数列这一需求,先明确从0、1起始的递推关系,再演示while循环的正确写法,并对比先更新后打印的典型错误。除了基础循环,还会介绍递归加缓存、生成器与itertools.takewhile等实现方式,帮助读者理解边界条件、惰性求值与输出格式控制。给出的代码均以数值不超过100作为停止条件,避免把项数当成数值边界。读完可以掌握一行输出、列表收集以及如何区分100以内和前100个斐波那契数。

斐波那契数列从0和1开始,后续每一项都是前两项之和。题目里的打印100以内,指的是只输出数值不超过100的所有项,而不是输出前100个项。这个边界条件如果处理不当,代码要么漏掉第一项,要么把超过100的144也打印出来。先看最简单的递推写法:用两个变量保存当前项和前一项,每次判断当前项是否小于等于100,再决定是否继续。

在Python如何打印100以内的斐波那契数列?

一、用递推变量构建基础循环

斐波那契数列的递推关系很直接:当前项等于前两项之和。程序里不需要保存整个列表,只需要维护两个变量 ab,分别表示当前项和下一项。初始时 a 为0,b 为1。循环只要判断当前项 a 是否满足 a <= 100,满足就打印,然后更新 ab

a, b = 0, 1
while a <= 100:
    print(a)
    a, b = b, a + b

上面这段代码的输出结果是:0、1、1、2、3、5、8、13、21、34、55、89。可以看到,89之后下一项是144,因为144大于100,循环条件不成立,所以不会打印144。这里的边界判断是数值边界,而不是项数边界。

代码中的 a, b = b, a + b 是Python的元组解包写法。右侧会先使用旧的 ab 计算出一个元组,然后同时赋值给左侧。也就是说,a 得到旧的 bb 得到旧的 a + b。这样做不需要额外的临时变量,代码更简洁,也不容易因为赋值顺序出错。

二、while循环实现中的常见错误

初学时很容易把更新和打印的顺序写反。例如下面这种写法虽然也能生成递推序列,但会输出越界值144:

a, b = 0, 1
while a <= 100:
    a, b = b, a + b
    print(a)

这段代码的问题在于,当 a 为89、b 为144时,循环条件 89 <= 100 仍然成立,程序进入循环体,先执行更新把 a 变成144,然后打印144。直到下一次判断 144 <= 100 不成立时才退出。因此输出序列会多出一个超过100的项。

正确做法是先打印当前项,再更新变量。打印和判断都应当基于当前项 a,而更新动作放在循环体的最后。只要保持这个顺序,while 循环就能准确地在144出现之前停止。

如果不想直接使用元组解包,也可以写成临时变量形式。先计算下一项,再更新:

a, b = 0, 1
while a <= 100:
    print(a)
    next_value = a + b
    a = b
    b = next_value

这种写法更接近其他编程语言的习惯,可读性也不错。但相比 a, b = b, a + b,多了一个 next_value 变量。实际开发中两者都可以,关键是保证当前项先被打印和判断。

三、递归与缓存的实现方式

斐波那契数列也可以通过递归定义实现。递归函数 fib(n) 返回第 n 项,基础情况是 n == 0 时返回0,n == 1 时返回1,其余情况返回前两项之和。如果要用递归打印100以内的数列,需要先确定最大项索引,然后逐个调用递归函数:

def fib(n):
    if n == 0:
        return 0
    if n == 1:
        return 1
    return fib(n - 1) + fib(n - 2)

i = 0
while fib(i) <= 100:
    print(fib(i))
    i += 1

这段代码虽然在逻辑上正确,但效率很低。每次调用 fib(i) 都会重新展开一棵递归树,已经计算过的值不会复用。随着 i 增大,重复计算次数呈指数级增长。对于100以内这个需求,最大项索引只有11左右,因此运行速度还能接受,但扩展到大数就会明显变慢。

可以引入 functools.lru_cache 来缓存已经计算过的递归结果,避免重复递归调用:

from functools import lru_cache

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

i = 0
while fib(i) <= 100:
    print(fib(i))
    i += 1

加上缓存后,每个 n 对应的斐波那契数只计算一次,之后直接从缓存读取。递归写法更贴近数学定义,适合用来理解递归思想。但就打印连续数列来说,它仍然不如递推循环简洁。实际工程中如果只需要序列,不推荐递归;如果要多次随机取某一项,缓存递归会更方便。

四、生成器方案与惰性求值

生成器是Python处理无限序列的常用方式。可以定义一个生成器函数,在无限循环中不断 yield 当前项,每次调用时只计算下一步,不会一次性生成所有项。打印100以内数列时可以借助 for 循环,当数值超过100时手动 break

def fib_series():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

for num in fib_series():
    if num > 100:
        break
    print(num)

生成器的优势在于惰性求值。代码不会提前算出144或其他超过100的项,而是每次迭代时用一次 next 调用得到一个新值。for 循环在发现 num > 100 后执行 break,生成器会在 yield 语句处暂停,后续不再继续计算后面的项。这样既节省内存,又使逻辑边界清晰。

如果想直接得到列表,而不是逐行打印,可以使用 itertools.takewhile。它会从可迭代对象中一直取元素,直到条件不满足为止:

from itertools import takewhile

def fib_series():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

result = list(takewhile(lambda x: x <= 100, fib_series()))
print(result)

整个表达式会返回 [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]。相比手动 breaktakewhile 更适合函数式风格,也能直接得到列表结果。需要注意 fib_series 本身是一个无限生成器,如果没有 takewhilebreak,直接对无限生成器调用 list 会导致程序一直运行下去。

五、输出格式与容易混淆的概念

默认情况下,print 每次调用都会自动换行,因此打印出来的每一项占一行。如果希望所有数列显示在同一行,可以给 print 传入 end=' ',用空格代替换行符:

def fib_series():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

for num in fib_series():
    if num > 100:
        break
    print(num, end=' ')
print()

这样输出结果就是 0 1 1 2 3 5 8 13 21 34 55 89。最后一个 print() 用来输出一个换行,防止后续提示符紧贴在数字后面。还可以把 end 改成其他分隔符,例如逗号加空格,但要注意末尾可能会多一个分隔符。

另一个容易混淆的地方是“100以内”和“前100个”的区别。100以内表示数值不超过100,数列长度由数值边界决定;前100个表示数量固定为100项,数值会很快超过100。打印前100项的代码控制的是项数,而不是数值大小:

a, b = 0, 1
for _ in range(100):
    print(a)
    a, b = b, a + b

这段代码会输出前100个斐波那契数,其中第100项已经是非常大的整数。实际使用时务必根据需求判断是控制数值上限还是控制项数。理解了这一点,再把 while 判断条件换成任意数值,比如200或1000,就能灵活打印不同范围内的斐波那契数列。

Python斐波那契数列while循环修改时间:2026-08-27 05:45:53

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。