Comparing Iterative and Recursive Factorial Functions
-
0:00 - 0:03我在这集视频里想要做的是 讲清楚
-
0:03 - 0:05“跌代”与递归之间的差别
-
0:05 - 0:07或者我应该说迭代
-
0:07 - 0:11我总是发音错误- 迭代函数的定义
-
0:11 - 0:16与递归函数定义的差别
-
0:16 - 0:18我们会通过这样的方法来完成比较
-
0:18 - 0:21理解这边的迭代函数是怎么样工作的
-
0:21 - 0:24以及右边这个递归函数是怎么样工作的
-
0:24 - 0:25那么当我们开始的时候
-
0:25 - 0:28会看到product被设置成1
-
0:28 - 0:30然后进入到for循环里
-
0:30 - 0:34而for循环实际上是
-
0:34 - 0:36迭代函数定义的“肉”
-
0:36 - 0:39而为了理解for循环里发生了什么
-
0:39 - 0:40我在这里做一个表格
-
0:40 - 0:44我给变量i的值做一个表格
-
0:44 - 0:46并且我也会找出
-
0:46 - 0:54变量product乘以i+1的值是什么
-
0:54 - 0:57因为在for循环的每次迭代中
-
0:57 - 0:59我们都会计算这里这个表达式的值
-
0:59 - 1:01然后我会给product的新值
-
1:01 - 1:03也做出一列表格
-
1:03 - 1:07product的新值
-
1:07 - 1:09我给它们标上下划线
-
1:09 - 1:12然后就有了product的新值
-
1:12 - 1:14我们在很久之前就知道
-
1:14 - 1:18在Python里的“for i in range”
-
1:18 - 1:20这里的range部分
-
1:20 - 1:23这里的range返回一列数
-
1:23 - 1:26它返回一列number的元素
-
1:26 - 1:29我们之前已经将其传递给number
-
1:29 - 1:32那么如果我们假设 我一开始就应该说的
-
1:32 - 1:34假设我们正调用-
-
1:34 - 1:35为了讲的更详细
-
1:35 - 1:45假设这是调用factorial(3)的结果
-
1:45 - 1:48那么我们传递给函数factorial的参数是3
-
1:48 - 1:52那么变量number就指向3
-
1:52 - 1:53当你调用range(number)时
-
1:53 - 1:58它就会按照字面意思那样返回一个数列[0,1,2]
-
1:58 - 2:00那么三个元素从0开始
-
2:00 - 2:03最后一个元素是3减1 也就是2
-
2:03 - 2:07那么在这个for循环的每次循环中
-
2:07 - 2:09变量i将会被依次赋值成
-
2:09 - 2:10数列里的数
-
2:10 - 2:13那么在for循环的第一次循环中
-
2:13 - 2:15i将会被赋值成0
-
2:15 - 2:18那么我们的i就将要指向0
-
2:18 - 2:22然后product乘以(i+1)
-
2:22 - 2:24好吧 在第一次循环时
-
2:24 - 2:28product在进入for循环之前就出现了 它被定义为1
-
2:28 - 2:32那么product就是1 而这个表达式就是1乘以-
-
2:32 - 2:36我不想用这个颜色来做
-
2:36 - 2:37我用-
-
2:37 - 2:39我用绛红色把它写出来-
-
2:39 - 2:471乘以i-- i是0 1乘以(0+1)
-
2:47 - 2:52加1 然后我们新的product的值就是
-
2:52 - 2:53将这个表达式计算出来的值
-
2:53 - 2:54就在这里
-
2:54 - 2:56product等于这堆东西
-
2:56 - 2:59那么我们新的值就是1乘以0加1
-
2:59 - 3:02就是1乘以1 也就是1
-
3:02 - 3:05这就是在循环语句内的所有东西了
-
3:05 - 3:06因为这就是在for循环里
-
3:06 - 3:08要完成的全部事情了
-
3:08 - 3:12然后我们回到上面去
-
3:12 - 3:14我们将会进行
-
3:14 - 3:16在for循环里的下一次迭代了
-
3:16 - 3:19我猜你们会说 现在i将被赋值成1了
-
3:19 - 3:22那么现在i等于1
-
3:22 - 3:24这里的这个表达式
-
3:24 - 3:26我们取product的旧值
-
3:26 - 3:30那么product还是1 所以product是1
-
3:30 - 3:40它要乘以i i现在是1了 1再加上1
-
3:40 - 3:42这等于什么呢?
-
3:42 - 3:46如果你把这些计算出来 就会得到1乘以2
-
3:46 - 3:48所以现在product的新值就是2
-
3:48 - 3:50那么在我们的第二次迭代后
-
3:50 - 3:53在我们第二次循环完成后
-
3:53 - 3:57现在它将会回到for循环的起点
-
3:57 - 4:00而i将赋值为数列里的下一个数
-
4:00 - 4:02它现在将被赋值成2
-
4:02 - 4:06那么现在i是2 而这里的这个东西 我们将会有-
-
4:06 - 4:09这个是product- product现在是2
-
4:09 - 4:14所以它就是2乘以i…
-
4:14 - 4:20而i现在是2 再加上1 那么它就是这样的
-
4:20 - 4:23它是2乘以3或者说6
-
4:23 - 4:27所以新的product是6 然后继续 我们会说:
-
4:27 - 4:30好吧 我们还能把i赋值成这里面的其他数吗?
-
4:30 - 4:32不行 我们已经用完了所有的数 所以我们会
-
4:32 - 4:35跳出for循环 然后我们返回product
-
4:35 - 4:40或者说变量product所指向的东西
-
4:40 - 4:41实际上这才是我应该说的东西
-
4:41 - 4:44应该返回product所指向的那个值
-
4:44 - 4:46那个值是6
-
4:46 - 4:50所以当你调用factorial(3) 它将返回6
-
4:50 - 4:52所以如果你说factorial-
-
4:52 - 4:58如果你要求factorial(3)加上factorial(3)
-
4:58 - 5:02那就要计算这个表达式
-
5:02 - 5:05这个表达式算出来是6
-
5:05 - 5:08而这里这个表达式算出的值也是6
-
5:08 - 5:10因为这就是函数返回的值
-
5:10 - 5:14然后如果你把它们加起来的话 就是12
-
5:14 - 5:16所以这就是我们为什么叫它迭代
-
5:16 - 5:20我们一直通过相同的一套指令来进行迭代
-
5:20 - 5:22现在让我们来比较一下递归的定义
-
5:22 - 5:25它在很多方面都更加有趣
-
5:25 - 5:28又一次 我们将调用factorial(3)
-
5:28 - 5:30factorial(3)
-
5:30 - 5:32所以3就是我们的参数
-
5:32 - 5:34而这就是number所指向的值
-
5:34 - 5:37然后判断number是否小于等于1
-
5:37 - 5:39好吧 3不小于等于1
-
5:39 - 5:40所以我们不会运行这部分的语句
-
5:40 - 5:42我们将会来到else语句
-
5:42 - 5:44那么我们将会返回number-
-
5:44 - 5:49我们要返回number乘以这个的阶乘
-
5:49 - 5:56所以它的值就会是number- number是3-
-
5:56 - 5:57那是我们传递的参数
-
5:57 - 6:08乘上number减1的阶乘
-
6:08 - 6:11而number减1的值是2 3减1等于2
-
6:11 - 6:12所以就是factorial(2)
-
6:12 - 6:15好吧 那是另一个调用factorial的函数
-
6:15 - 6:15所以我们返回去
-
6:15 - 6:19还是factorial函数 只是参数现在是2 所以number是2
-
6:19 - 6:22我们继续 如果number小于等于1 我们执行这条语句
-
6:22 - 6:23但是number没有小于等于1
-
6:23 - 6:25它是2 所以我们转到else部分
-
6:25 - 6:28那么我们现在想要返回的是
-
6:28 - 6:30number乘上factorial(number-1)
-
6:30 - 6:31那么在这个情况下…
-
6:31 - 6:35在这个情况下 number现在是2
-
6:35 - 6:38而现在我们要将它乘上
-
6:38 - 6:44乘上factorial(2-1)
-
6:44 - 6:45好吧 2减1就是1
-
6:45 - 6:47乘以factorial(1)
-
6:47 - 6:49好吧 我们又做了一个函数调用
-
6:49 - 6:52那么解释器不得不记住
-
6:52 - 6:53我们做的这一系列的函数调用
-
6:53 - 6:56并不得不一直向更深处挖掘
-
6:56 - 6:58那么现在 我们调用了factorial(1)
-
6:58 - 7:01factorial(1) 1是参数
-
7:01 - 7:02number现在指向1
-
7:02 - 7:04如果number小于等于1
-
7:04 - 7:05number确实小于等于1
-
7:05 - 7:07现在这就是我们所称的基本情况
-
7:07 - 7:08我们一直在走向它
-
7:08 - 7:12那么number小于等于1 返回1
-
7:12 - 7:13那么在这个情况下
-
7:13 - 7:16当我们调用factorial(1) 它就会返回1
-
7:16 - 7:18所以我们现在知道了
-
7:18 - 7:23factorial(2)等于2乘以1
-
7:23 - 7:26那么这就等于2
-
7:26 - 7:29我们知道factorial(3)等于3乘以2
-
7:29 - 7:36也就是6
-
7:36 - 7:38所以 非常不一样的思考方式
-
7:38 - 7:40却得到了完全一样的结果
-
7:40 - 7:42又一次 如果你计算factorial(3)加上factorial(3)
-
7:42 - 7:44你用哪种方式来完成它并没关系
-
7:44 - 7:47我们会得到6加6或者说12