递归函数不是帝龟啊!:一个函数调用了它自己本身就叫做递归
定义一个比较糟糕的函数调用自身:
你会发现它调用test()的时候,它唯一的函数内容是打印myoffer然后returntest(),再回到定义函数,打印myoffer,然后return test()一直循环往复;
这就有疑问了
是不是会一直执行下去呢,理论上它会一直执行下去直到消耗掉所有内存,其实Python3设置了递归默认深度是100层,到达之后就会报错。不过在写爬虫工具的时候就可能不止100层了,所以我们就要自力更生了。
这样深层次的调用就会导致“栈溢出”就好比一个杯子它有自己的最大容量,超过了这个容量就会溢出。
来个人道点的例子解释帝龟和栈溢出:求1-100的阶乘。
先分析:
想要得到的结果1×2×3×…×100
可以拆分成100×函数(99)【函数(99)可以完成1×2×3×…×99 】
可以拆分成 99×函数(98)【函数(99)可以完成1×2×3×…×98】
……
……
…….
可以拆分成2×函数(1)【函数(1)可以完成1×2】正确的解法如下
现在来了解一下这只龟,先拿一个print(test(3))来剖析
第一次程序执行时会先传入3,替换所有numbers,当执行到test(3-1)又要调用test()然后就会传入2,变为test(numbers=2)下面的程序。
同理执行到test(2-1)又要再次调用test(),变为test(numbers=1)下面的程序
直接执行else后的程序返回1
注意:一个函数调用return有两种含义:返回一个值或结束当前函数;
所以说当return 1时第二个程序中的test(2-1)就会替换为return 2×1
接着就会执行这个return 2×1时,第一个程序中的test(3-1)就会替换为return 3×2×1
当执行这个return 3×2×1时,程序就会执行结果print(test(3)),同理要执行print(test(100))也是一样的原理,这就是帝龟。
好啦现在理解了帝龟就可以更透彻明白栈溢出了
第一步当程序执行print(test(3))这玩意的时候,就要调用函数test(number=3),然后执行下面这个函数
执行好后呢,先把这个3放到杯子底下,然后执行numbers=2,就把2再放到杯子里,一层层上叠(就是在内存中存储好,为了当返回执行return2×1时,能够识别3×test(3-1)并替换为return 3×2×1,其它的类似,当返回执行return1时,能够识别2×test(2-1)并替换为return 2×1)
所以说每次调用自己函数的时候呢就要在杯子中装点东西,当你调用循环的次数是1000000或者更大,杯子总有满的时候,等到装不下的时候就叫做“栈溢出”了。
至于为甚么叫“栈(stack)溢出”怎么上档次的名字呢
上面说了存东西的时候都是从杯底往上一层层的叠加(调用一次函数,栈就会加一层栈帧),到你要取的时候只能先从上面拿了(函数返回栈就会减一层栈帧),杯子是有最大容量的(栈的大小不是无限的,递归调用过多就会栈溢出)总结:这种存储特性“先进后出”
注意:为什么上面的例子numbers=1要多带带处理呢,因为当numbers传入1时,就会变成test(1-1),没有到0的阶乘,这样结果就会变成0.
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/41545.html
摘要:再调用个绝对值内置函数来加深影响心急吃不了热豆腐啊有且仅能传入一个参数,传入不符合数量的参数就会报错误传入的参数数量是没错了,但传入错误的参数类型也是会死的很惨的。 调用函数 干货:Python官网查看函数帮助信息 http://docs.python.org/3/libr... showImg(https://segmentfault.com/img/bV71Kn?w=348&h=8...
摘要:理解了输入输出,就可以简单的打印有意义的程序了比如打印先输入回车输入或其它内容,存入变量输入当然为了用户体验更好,可以适当的添加一些提示信息数据类型和变量整数常用十六进制表示与数学上表示方法一样等。常量不能变的量,通常用大写字母表示 1、输出函数:Print() 接受多个字符串时用逗号隔开(相当于空格),就可连成一串输出。 showImg(https://segmentfault.co...
摘要:本文是通过廖雪峰的网站学习而整理的真的是很好的教程,省得我花钱买书了,然后我没有去再整理总结语法,而是直接通过写出代码段来体现自己的学习,也方便以后的快速复习回顾。 不想再像以前那样,什么都从头开始学习语法、总结语法,这样反而会过分纠结于语法,耽误了开发,毕竟语言的主要属性是工具,次要的属性是语言本身。 所以还是先熟练使用语言去进行开发,等足够熟悉了,再去研究语言本身(编译原理……)。...
摘要:同样的用上节讲的函数获取元素的个数记住这是获取的是列表个数个数个数重要的事说三遍。用索引访问每个元素的位置,索引是从开始的开始的开始的索引也是有容忍限度的超过了就会原地爆炸报错如果列表中元素个数贼多,想获取后面的元素就要实行曲线救国了。 list和tuple是Python内置的有序集合,一个是可变的,一个是不可变滴;这都不是事,主要是理解一下指向不变。 看图说话: showImg(ht...
阅读 1038·2021-11-18 13:23
阅读 745·2021-11-08 13:16
阅读 854·2021-10-11 10:58
阅读 3509·2021-09-22 15:26
阅读 1730·2021-09-08 10:42
阅读 1806·2021-09-04 16:45
阅读 1732·2019-08-30 15:54
阅读 2563·2019-08-30 13:45