- 教程
- 文档
【免费下载链接】30-seconds-of-python
Short Python code snippets for all your development needs
斐波那契数列是最经典的算法入门问题之一,本仓库 snippets/fibonacci.md 以“30 秒一个切片”的极简风格给出了一个基于迭代的 Python 实现:从0、1出发,用list.append()不断累加最后两项,直到序列长度达到n。读完本文,你将理解该函数的逐行执行流程、边界条件与复杂度特征,并能将其与仓库内其他数学/列表切片(如等差数列、等比数列、取前n个元素等)配套使用。
切片定位:一篇 Snippet 的标准形态
本仓库(30-seconds-of-python)以“Short Python code snippets for all your development needs”为宗旨,每个切片都是独立的 Markdown 文件,遵循 snippet-template.md 定义的统一格式。以fibonacci切片为例,其文件头包含标准 frontmatter:
--- title: Fibonacci type: snippet tags: [math,list] cover: san-francisco-skyline dateModified: 2020-11-02T19:27:53+02:00 ---title:切片名称,用于站内检索与展示;type:固定为snippet;tags:分类标签,此处标记为math(数学)与list(列表),便于按标签浏览;dateModified:内容最后修改时间。
正文部分则严格遵循“一段功能描述 + 若干要点说明 + 核心实现 + 一行示例”的骨架,全部内容面向可快速复制、即拿即用。
完整实现与一行示例
原始切片提供的代码如下:
def fibonacci(n): if n <= 0: return [0] sequence = [0, 1] while len(sequence) <= n: next_value = sequence[len(sequence) - 1] + sequence[len(sequence) - 2] sequence.append(next_value) return sequence对应的示例用法与预期输出:
fibonacci(7) # [0, 1, 1, 2, 3, 5, 8, 13]逐行解读:迭代如何“滚动”生成数列
函数的核心思路是:从两个初始值开始,每次把列表末尾两项之和追加到末尾,使序列自我生长。具体执行过程如下:
边界守卫:
if n <= 0: return [0]。当n小于等于0时,直接返回只含0的列表。这保证了负数和0作为参数时函数不会进入后续循环,行为稳定可预期。初始化种子:
sequence = [0, 1],即斐波那契数列的起始两项。滚动累加:
while len(sequence) <= n控制循环次数——只要当前列表长度尚未超过n,就继续追加。循环体内:sequence[len(sequence) - 1]与sequence[len(sequence) - 2]分别取出当前列表的最后一项与倒数第二项,二者之和即下一个斐波那契数;sequence.append(next_value)使用list.append()将其追加到末尾。
返回结果:循环结束后返回完整列表。
执行轨迹演示
以fibonacci(7)为例,逐步跟踪:
| 步骤 | 循环前列表长度 | 追加值 | 追加后列表 |
|---|---|---|---|
| 初始化 | 2 | – | [0, 1] |
| 第 1 轮 | 2 ≤ 7 | 1+0=1 | [0, 1, 1] |
| 第 2 轮 | 3 ≤ 7 | 1+1=2 | [0, 1, 1, 2] |
| 第 3 轮 | 4 ≤ 7 | 2+1=3 | [0, 1, 1, 2, 3] |
| 第 4 轮 | 5 ≤ 7 | 3+2=5 | [0, 1, 1, 2, 3, 5] |
| 第 5 轮 | 6 ≤ 7 | 5+3=8 | [0, 1, 1, 2, 3, 5, 8] |
| 第 6 轮 | 7 ≤ 7 | 8+5=13 | [0, 1, 1, 2, 3, 5, 8, 13] |
| 终止 | 8 > 7 | – | 返回[0, 1, 1, 2, 3, 5, 8, 13] |
从轨迹可见,返回列表的长度为n + 1(此处为 8 个元素),下标从0到n,与“生成直到第n项”的语义一致。
边界条件与返回值语义
切片的说明文档明确了两条语义规则,代码也与之完全对应:
n <= 0时返回[0]:无论传入0、负整数还是其他非正数,返回值恒为单元素列表[0],不会进入循环,也不会抛出异常。n = 1时返回[0, 1]:此时sequence初始长度已是2,while len(sequence) <= 1不成立,直接返回种子列表。换言之,该实现返回的列表始终以0、1开头,即使调用方只想要前两项,也拿不到比[0, 1]更短的序列。这是该切片的一个实现特性,使用前应当知晓。
复杂度分析
从源码结构可以直接推断:
- 时间复杂度 O(n):循环恰好执行
n - 1轮(n ≥ 1时),每轮只有常数次索引取值与加法,整体与n呈线性关系; - 空间复杂度 O(n):结果列表需要容纳
n + 1个整数,且原列表原地通过append增长,没有额外的中间数据结构。
与递归写法相比,这种迭代实现不存在指数级重复计算问题,也没有深递归导致的栈溢出风险,是工程上稳妥的选择。
在仓库切片生态中的位置
本仓库将fibonacci归类为[math,list]标签切片,与其相邻的同类实现可以组合出不少实用场景:
- 数列类:等差数列 snippets/arithmetic-progression.md(
arithmetic_progression(5, 25)生成[5, 10, 15, 20, 25])、等比数列 snippets/geometric-progression.md(支持自定义起点与公比); - 幂和类:snippets/sum-of-powers.md 用列表推导与
sum()计算区间内各数的幂之和; - 数值判断类:snippets/is-even.md 通过取模判断奇偶,可用于对斐波那契数列做奇偶过滤;
- 列表操作类:如需截取斐波那契序列的前若干项或取首项,可与 snippets/take.md(
itr[:n]截取前n个元素)和 snippets/head.md(lst[0]取首元素)配合使用; - 数学工具类:求数列中多个数的最大公约数可用 snippets/gcd.md(基于
functools.reduce与math.gcd)。
延伸:如需改写,可考虑的方向
本切片的迭代写法已经足够简短高效,但如果你的场景有特殊要求,以下几类通用做法(均为社区常见实践,非本仓库内置实现)值得参考:
- 生成器版本:将
return改为yield,逐项产出斐波那契数,适合按需消费、避免一次性占满内存的长序列场景; - 缓存/记忆化:用字典缓存已算过的结果,避免递归版本中的重复计算;
- 通项公式(Binet 公式):用黄金比例的直接公式计算第
n项,时间复杂度可降至 O(1),但浮点精度在大n下会失真,仅适合精度要求不高的场景。
注意事项小结
fibonacci(n)返回的是包含第 0 项到第 n 项的列表(长度n + 1),而非仅包含前n项;- 当
n较大时,列表中的整数会迅速增长为长整型,内存占用随之上升,需结合实际业务量评估; - 该实现不接受负数项以外的语义定制;如需从自定义起点生成,可参考等比数列切片对默认参数的处理方式自行扩展。
综上,snippets/fibonacci.md 用不到十行代码讲清楚了斐波那契数列迭代生成的完整逻辑,是理解“用列表结构自增长解决问题”的绝佳示例,也是 30-seconds-of-python 中math与list标签交叉的典型切片。
- 教程
- 文档
【免费下载链接】30-seconds-of-python
Short Python code snippets for all your development needs
相关推荐
30 Seconds of Code 实战:用 JavaScript 生成斐波那契数列(迭代与递归双方案)
30 Seconds of Code 实战:用 JavaScript 生成斐波那契数列(迭代与递归双方案) 本篇技术指南以 30 seconds of code
教程文档30 Seconds of Interviews:用 Array.reduce 生成斐波那契数列数组的 JavaScript 实现与面试拆解
30 Seconds of Interviews:用 Array.reduce 生成斐波那契数列数组的 JavaScript 实现与面试拆解 导读 本文围绕 3
教程前端Dub.co:如何用智能链接管理平台打造高转化二维码的完整指南
Dub.co:如何用智能链接管理平台打造高转化二维码的完整指南 你是否曾为那些单调的黑白二维码感到厌倦?或者为无法追踪二维码扫描效果而烦恼?Dub.co作为现代
后端前端数据分析
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考