[Script Info] Title: [Events] Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text Dialogue: 0,0:00:00.06,0:00:02.54,Default,,0000,0000,0000,,我在这集视频里想要做的是 讲清楚 Dialogue: 0,0:00:02.54,0:00:05.10,Default,,0000,0000,0000,,“跌代”与递归之间的差别 Dialogue: 0,0:00:05.10,0:00:06.87,Default,,0000,0000,0000,,或者我应该说迭代 Dialogue: 0,0:00:06.87,0:00:10.55,Default,,0000,0000,0000,,我总是发音错误- 迭代函数的定义 Dialogue: 0,0:00:10.55,0:00:15.90,Default,,0000,0000,0000,,与递归函数定义的差别 Dialogue: 0,0:00:15.90,0:00:18.03,Default,,0000,0000,0000,,我们会通过这样的方法来完成比较 Dialogue: 0,0:00:18.03,0:00:21.03,Default,,0000,0000,0000,,理解这边的迭代函数是怎么样工作的 Dialogue: 0,0:00:21.03,0:00:23.78,Default,,0000,0000,0000,,以及右边这个递归函数是怎么样工作的 Dialogue: 0,0:00:23.78,0:00:25.26,Default,,0000,0000,0000,,那么当我们开始的时候 Dialogue: 0,0:00:25.26,0:00:28.03,Default,,0000,0000,0000,,会看到product被设置成1 Dialogue: 0,0:00:28.03,0:00:29.94,Default,,0000,0000,0000,,然后进入到for循环里 Dialogue: 0,0:00:29.94,0:00:33.88,Default,,0000,0000,0000,,而for循环实际上是 Dialogue: 0,0:00:33.88,0:00:36.20,Default,,0000,0000,0000,,迭代函数定义的“肉” Dialogue: 0,0:00:36.20,0:00:38.82,Default,,0000,0000,0000,,而为了理解for循环里发生了什么 Dialogue: 0,0:00:38.82,0:00:40.06,Default,,0000,0000,0000,,我在这里做一个表格 Dialogue: 0,0:00:40.06,0:00:43.95,Default,,0000,0000,0000,,我给变量i的值做一个表格 Dialogue: 0,0:00:43.95,0:00:46.26,Default,,0000,0000,0000,,并且我也会找出 Dialogue: 0,0:00:46.26,0:00:53.73,Default,,0000,0000,0000,,变量product乘以i+1的值是什么 Dialogue: 0,0:00:53.73,0:00:56.55,Default,,0000,0000,0000,,因为在for循环的每次迭代中 Dialogue: 0,0:00:56.55,0:00:58.97,Default,,0000,0000,0000,,我们都会计算这里这个表达式的值 Dialogue: 0,0:00:58.97,0:01:01.31,Default,,0000,0000,0000,,然后我会给product的新值 Dialogue: 0,0:01:01.31,0:01:03.48,Default,,0000,0000,0000,,也做出一列表格 Dialogue: 0,0:01:03.48,0:01:06.83,Default,,0000,0000,0000,,product的新值 Dialogue: 0,0:01:06.83,0:01:09.03,Default,,0000,0000,0000,,我给它们标上下划线 Dialogue: 0,0:01:09.03,0:01:12.10,Default,,0000,0000,0000,,然后就有了product的新值 Dialogue: 0,0:01:12.10,0:01:14.20,Default,,0000,0000,0000,,我们在很久之前就知道 Dialogue: 0,0:01:14.20,0:01:17.50,Default,,0000,0000,0000,,在Python里的“for i in range” Dialogue: 0,0:01:17.50,0:01:19.70,Default,,0000,0000,0000,,这里的range部分 Dialogue: 0,0:01:19.70,0:01:22.87,Default,,0000,0000,0000,,这里的range返回一列数 Dialogue: 0,0:01:22.87,0:01:26.10,Default,,0000,0000,0000,,它返回一列number的元素 Dialogue: 0,0:01:26.10,0:01:29.27,Default,,0000,0000,0000,,我们之前已经将其传递给number Dialogue: 0,0:01:29.27,0:01:32.09,Default,,0000,0000,0000,,那么如果我们假设 我一开始就应该说的 Dialogue: 0,0:01:32.09,0:01:33.91,Default,,0000,0000,0000,,假设我们正调用- Dialogue: 0,0:01:33.91,0:01:35.44,Default,,0000,0000,0000,,为了讲的更详细 Dialogue: 0,0:01:35.44,0:01:45.08,Default,,0000,0000,0000,,假设这是调用factorial(3)的结果 Dialogue: 0,0:01:45.08,0:01:47.53,Default,,0000,0000,0000,,那么我们传递给函数factorial的参数是3 Dialogue: 0,0:01:47.53,0:01:51.71,Default,,0000,0000,0000,,那么变量number就指向3 Dialogue: 0,0:01:51.71,0:01:53.49,Default,,0000,0000,0000,,当你调用range(number)时 Dialogue: 0,0:01:53.49,0:01:58.45,Default,,0000,0000,0000,,它就会按照字面意思那样返回一个数列[0,1,2] Dialogue: 0,0:01:58.45,0:01:59.94,Default,,0000,0000,0000,,那么三个元素从0开始 Dialogue: 0,0:01:59.94,0:02:03.33,Default,,0000,0000,0000,,最后一个元素是3减1 也就是2 Dialogue: 0,0:02:03.33,0:02:06.68,Default,,0000,0000,0000,,那么在这个for循环的每次循环中 Dialogue: 0,0:02:06.68,0:02:09.43,Default,,0000,0000,0000,,变量i将会被依次赋值成 Dialogue: 0,0:02:09.43,0:02:09.82,Default,,0000,0000,0000,,数列里的数 Dialogue: 0,0:02:09.82,0:02:12.58,Default,,0000,0000,0000,,那么在for循环的第一次循环中 Dialogue: 0,0:02:12.58,0:02:14.68,Default,,0000,0000,0000,,i将会被赋值成0 Dialogue: 0,0:02:14.68,0:02:17.89,Default,,0000,0000,0000,,那么我们的i就将要指向0 Dialogue: 0,0:02:17.89,0:02:21.88,Default,,0000,0000,0000,,然后product乘以(i+1) Dialogue: 0,0:02:21.88,0:02:24.49,Default,,0000,0000,0000,,好吧 在第一次循环时 Dialogue: 0,0:02:24.49,0:02:27.98,Default,,0000,0000,0000,,product在进入for循环之前就出现了 它被定义为1 Dialogue: 0,0:02:27.98,0:02:32.24,Default,,0000,0000,0000,,那么product就是1 而这个表达式就是1乘以- Dialogue: 0,0:02:32.24,0:02:35.76,Default,,0000,0000,0000,,我不想用这个颜色来做 Dialogue: 0,0:02:35.76,0:02:36.71,Default,,0000,0000,0000,,我用- Dialogue: 0,0:02:36.71,0:02:38.90,Default,,0000,0000,0000,,我用绛红色把它写出来- Dialogue: 0,0:02:38.90,0:02:47.37,Default,,0000,0000,0000,,1乘以i-- i是0 1乘以(0+1) Dialogue: 0,0:02:47.37,0:02:51.70,Default,,0000,0000,0000,,加1 然后我们新的product的值就是 Dialogue: 0,0:02:51.70,0:02:53.03,Default,,0000,0000,0000,,将这个表达式计算出来的值 Dialogue: 0,0:02:53.03,0:02:53.88,Default,,0000,0000,0000,,就在这里 Dialogue: 0,0:02:53.88,0:02:56.45,Default,,0000,0000,0000,,product等于这堆东西 Dialogue: 0,0:02:56.45,0:02:59.16,Default,,0000,0000,0000,,那么我们新的值就是1乘以0加1 Dialogue: 0,0:02:59.16,0:03:01.53,Default,,0000,0000,0000,,就是1乘以1 也就是1 Dialogue: 0,0:03:01.53,0:03:05.13,Default,,0000,0000,0000,,这就是在循环语句内的所有东西了 Dialogue: 0,0:03:05.13,0:03:06.04,Default,,0000,0000,0000,,因为这就是在for循环里 Dialogue: 0,0:03:06.04,0:03:08.34,Default,,0000,0000,0000,,要完成的全部事情了 Dialogue: 0,0:03:08.34,0:03:11.63,Default,,0000,0000,0000,,然后我们回到上面去 Dialogue: 0,0:03:11.63,0:03:14.19,Default,,0000,0000,0000,,我们将会进行 Dialogue: 0,0:03:14.19,0:03:15.96,Default,,0000,0000,0000,,在for循环里的下一次迭代了 Dialogue: 0,0:03:15.96,0:03:19.47,Default,,0000,0000,0000,,我猜你们会说 现在i将被赋值成1了 Dialogue: 0,0:03:19.47,0:03:22.42,Default,,0000,0000,0000,,那么现在i等于1 Dialogue: 0,0:03:22.42,0:03:23.87,Default,,0000,0000,0000,,这里的这个表达式 Dialogue: 0,0:03:23.87,0:03:25.73,Default,,0000,0000,0000,,我们取product的旧值 Dialogue: 0,0:03:25.73,0:03:30.04,Default,,0000,0000,0000,,那么product还是1 所以product是1 Dialogue: 0,0:03:30.04,0:03:39.99,Default,,0000,0000,0000,,它要乘以i i现在是1了 1再加上1 Dialogue: 0,0:03:39.99,0:03:41.90,Default,,0000,0000,0000,,这等于什么呢? Dialogue: 0,0:03:41.90,0:03:45.51,Default,,0000,0000,0000,,如果你把这些计算出来 就会得到1乘以2 Dialogue: 0,0:03:45.51,0:03:48.23,Default,,0000,0000,0000,,所以现在product的新值就是2 Dialogue: 0,0:03:48.23,0:03:49.99,Default,,0000,0000,0000,,那么在我们的第二次迭代后 Dialogue: 0,0:03:49.99,0:03:53.40,Default,,0000,0000,0000,,在我们第二次循环完成后 Dialogue: 0,0:03:53.40,0:03:56.96,Default,,0000,0000,0000,,现在它将会回到for循环的起点 Dialogue: 0,0:03:56.96,0:03:59.70,Default,,0000,0000,0000,,而i将赋值为数列里的下一个数 Dialogue: 0,0:03:59.70,0:04:02.32,Default,,0000,0000,0000,,它现在将被赋值成2 Dialogue: 0,0:04:02.32,0:04:06.23,Default,,0000,0000,0000,,那么现在i是2 而这里的这个东西 我们将会有- Dialogue: 0,0:04:06.23,0:04:08.51,Default,,0000,0000,0000,,这个是product- product现在是2 Dialogue: 0,0:04:08.51,0:04:13.52,Default,,0000,0000,0000,,所以它就是2乘以i… Dialogue: 0,0:04:13.52,0:04:20.08,Default,,0000,0000,0000,,而i现在是2 再加上1 那么它就是这样的 Dialogue: 0,0:04:20.08,0:04:23.26,Default,,0000,0000,0000,,它是2乘以3或者说6 Dialogue: 0,0:04:23.26,0:04:27.16,Default,,0000,0000,0000,,所以新的product是6 然后继续 我们会说: Dialogue: 0,0:04:27.16,0:04:30.10,Default,,0000,0000,0000,,好吧 我们还能把i赋值成这里面的其他数吗? Dialogue: 0,0:04:30.10,0:04:32.21,Default,,0000,0000,0000,,不行 我们已经用完了所有的数 所以我们会 Dialogue: 0,0:04:32.21,0:04:35.10,Default,,0000,0000,0000,,跳出for循环 然后我们返回product Dialogue: 0,0:04:35.10,0:04:39.89,Default,,0000,0000,0000,,或者说变量product所指向的东西 Dialogue: 0,0:04:39.89,0:04:41.30,Default,,0000,0000,0000,,实际上这才是我应该说的东西 Dialogue: 0,0:04:41.30,0:04:44.06,Default,,0000,0000,0000,,应该返回product所指向的那个值 Dialogue: 0,0:04:44.06,0:04:46.30,Default,,0000,0000,0000,,那个值是6 Dialogue: 0,0:04:46.30,0:04:49.75,Default,,0000,0000,0000,,所以当你调用factorial(3) 它将返回6 Dialogue: 0,0:04:49.75,0:04:52.05,Default,,0000,0000,0000,,所以如果你说factorial- Dialogue: 0,0:04:52.05,0:04:57.96,Default,,0000,0000,0000,,如果你要求factorial(3)加上factorial(3) Dialogue: 0,0:04:57.96,0:05:01.80,Default,,0000,0000,0000,,那就要计算这个表达式 Dialogue: 0,0:05:01.80,0:05:05.37,Default,,0000,0000,0000,,这个表达式算出来是6 Dialogue: 0,0:05:05.37,0:05:08.33,Default,,0000,0000,0000,,而这里这个表达式算出的值也是6 Dialogue: 0,0:05:08.33,0:05:09.96,Default,,0000,0000,0000,,因为这就是函数返回的值 Dialogue: 0,0:05:09.96,0:05:13.86,Default,,0000,0000,0000,,然后如果你把它们加起来的话 就是12 Dialogue: 0,0:05:13.86,0:05:15.70,Default,,0000,0000,0000,,所以这就是我们为什么叫它迭代 Dialogue: 0,0:05:15.70,0:05:19.76,Default,,0000,0000,0000,,我们一直通过相同的一套指令来进行迭代 Dialogue: 0,0:05:19.76,0:05:22.31,Default,,0000,0000,0000,,现在让我们来比较一下递归的定义 Dialogue: 0,0:05:22.31,0:05:24.55,Default,,0000,0000,0000,,它在很多方面都更加有趣 Dialogue: 0,0:05:24.55,0:05:27.60,Default,,0000,0000,0000,,又一次 我们将调用factorial(3) Dialogue: 0,0:05:27.60,0:05:30.08,Default,,0000,0000,0000,,factorial(3) Dialogue: 0,0:05:30.08,0:05:32.24,Default,,0000,0000,0000,,所以3就是我们的参数 Dialogue: 0,0:05:32.24,0:05:34.24,Default,,0000,0000,0000,,而这就是number所指向的值 Dialogue: 0,0:05:34.24,0:05:36.65,Default,,0000,0000,0000,,然后判断number是否小于等于1 Dialogue: 0,0:05:36.65,0:05:38.70,Default,,0000,0000,0000,,好吧 3不小于等于1 Dialogue: 0,0:05:38.70,0:05:40.22,Default,,0000,0000,0000,,所以我们不会运行这部分的语句 Dialogue: 0,0:05:40.22,0:05:41.63,Default,,0000,0000,0000,,我们将会来到else语句 Dialogue: 0,0:05:41.63,0:05:44.14,Default,,0000,0000,0000,,那么我们将会返回number- Dialogue: 0,0:05:44.14,0:05:48.85,Default,,0000,0000,0000,,我们要返回number乘以这个的阶乘 Dialogue: 0,0:05:48.85,0:05:55.54,Default,,0000,0000,0000,,所以它的值就会是number- number是3- Dialogue: 0,0:05:55.54,0:05:57.18,Default,,0000,0000,0000,,那是我们传递的参数 Dialogue: 0,0:05:57.18,0:06:07.62,Default,,0000,0000,0000,,乘上number减1的阶乘 Dialogue: 0,0:06:07.62,0:06:10.89,Default,,0000,0000,0000,,而number减1的值是2 3减1等于2 Dialogue: 0,0:06:10.89,0:06:12.37,Default,,0000,0000,0000,,所以就是factorial(2) Dialogue: 0,0:06:12.37,0:06:14.76,Default,,0000,0000,0000,,好吧 那是另一个调用factorial的函数 Dialogue: 0,0:06:14.76,0:06:15.49,Default,,0000,0000,0000,,所以我们返回去 Dialogue: 0,0:06:15.49,0:06:18.74,Default,,0000,0000,0000,,还是factorial函数 只是参数现在是2 所以number是2 Dialogue: 0,0:06:18.74,0:06:21.54,Default,,0000,0000,0000,,我们继续 如果number小于等于1 我们执行这条语句 Dialogue: 0,0:06:21.54,0:06:22.96,Default,,0000,0000,0000,,但是number没有小于等于1 Dialogue: 0,0:06:22.96,0:06:24.72,Default,,0000,0000,0000,,它是2 所以我们转到else部分 Dialogue: 0,0:06:24.72,0:06:28.20,Default,,0000,0000,0000,,那么我们现在想要返回的是 Dialogue: 0,0:06:28.20,0:06:30.04,Default,,0000,0000,0000,,number乘上factorial(number-1) Dialogue: 0,0:06:30.04,0:06:31.49,Default,,0000,0000,0000,,那么在这个情况下… Dialogue: 0,0:06:31.49,0:06:34.54,Default,,0000,0000,0000,,在这个情况下 number现在是2 Dialogue: 0,0:06:34.54,0:06:37.82,Default,,0000,0000,0000,,而现在我们要将它乘上 Dialogue: 0,0:06:37.82,0:06:43.66,Default,,0000,0000,0000,,乘上factorial(2-1) Dialogue: 0,0:06:43.66,0:06:45.21,Default,,0000,0000,0000,,好吧 2减1就是1 Dialogue: 0,0:06:45.21,0:06:46.89,Default,,0000,0000,0000,,乘以factorial(1) Dialogue: 0,0:06:46.89,0:06:48.55,Default,,0000,0000,0000,,好吧 我们又做了一个函数调用 Dialogue: 0,0:06:48.55,0:06:51.60,Default,,0000,0000,0000,,那么解释器不得不记住 Dialogue: 0,0:06:51.60,0:06:53.09,Default,,0000,0000,0000,,我们做的这一系列的函数调用 Dialogue: 0,0:06:53.09,0:06:55.62,Default,,0000,0000,0000,,并不得不一直向更深处挖掘 Dialogue: 0,0:06:55.62,0:06:57.52,Default,,0000,0000,0000,,那么现在 我们调用了factorial(1) Dialogue: 0,0:06:57.52,0:07:00.66,Default,,0000,0000,0000,,factorial(1) 1是参数 Dialogue: 0,0:07:00.66,0:07:01.91,Default,,0000,0000,0000,,number现在指向1 Dialogue: 0,0:07:01.91,0:07:03.81,Default,,0000,0000,0000,,如果number小于等于1 Dialogue: 0,0:07:03.81,0:07:05.40,Default,,0000,0000,0000,,number确实小于等于1 Dialogue: 0,0:07:05.40,0:07:06.66,Default,,0000,0000,0000,,现在这就是我们所称的基本情况 Dialogue: 0,0:07:06.66,0:07:08.04,Default,,0000,0000,0000,,我们一直在走向它 Dialogue: 0,0:07:08.04,0:07:11.53,Default,,0000,0000,0000,,那么number小于等于1 返回1 Dialogue: 0,0:07:11.53,0:07:13.19,Default,,0000,0000,0000,,那么在这个情况下 Dialogue: 0,0:07:13.19,0:07:16.42,Default,,0000,0000,0000,,当我们调用factorial(1) 它就会返回1 Dialogue: 0,0:07:16.42,0:07:17.72,Default,,0000,0000,0000,,所以我们现在知道了 Dialogue: 0,0:07:17.72,0:07:22.91,Default,,0000,0000,0000,,factorial(2)等于2乘以1 Dialogue: 0,0:07:22.91,0:07:26.41,Default,,0000,0000,0000,,那么这就等于2 Dialogue: 0,0:07:26.41,0:07:29.44,Default,,0000,0000,0000,,我们知道factorial(3)等于3乘以2 Dialogue: 0,0:07:29.44,0:07:35.84,Default,,0000,0000,0000,,也就是6 Dialogue: 0,0:07:35.84,0:07:38.03,Default,,0000,0000,0000,,所以 非常不一样的思考方式 Dialogue: 0,0:07:38.03,0:07:39.54,Default,,0000,0000,0000,,却得到了完全一样的结果 Dialogue: 0,0:07:39.54,0:07:42.14,Default,,0000,0000,0000,,又一次 如果你计算factorial(3)加上factorial(3) Dialogue: 0,0:07:42.14,0:07:44.08,Default,,0000,0000,0000,,你用哪种方式来完成它并没关系 Dialogue: 0,0:07:44.08,0:07:46.53,Default,,0000,0000,0000,,我们会得到6加6或者说12