100周Python进阶:第一周:构建一个简单的斐波那契数列函数-创新互联
目录
你所需要的网站建设服务,我们均能行业靠前的水平为你提供.标准是产品质量的保证,主要从事网站制作、成都网站建设、企业网站建设、手机网站开发、网页设计、高端网站设计、网页制作、做网站、建网站。成都创新互联公司拥有实力坚强的技术研发团队及素养的视觉设计专才。一、写在前面的话:
二、代码实现
2.1 简介
2.2 构思
2.3 代码实现与剖析
2.3.1 def语句、命名规范以及为什么要使用函数
2.3.2 关于形参与实参
2.3.3 文档字符串
2.3.4 简洁的赋值方式:a, b = 0, 1
2.3.5 while循环与print函数
2.3.6 try...except...语句,以及关于多态的简单介绍
2.4 改进方案
2.5 其他的解法(关于递归)
一、写在前面的话:
作为一个可怜的中学生,做什么事情都三分钟热度,因此写下这个100周的计划强迫自己坚持(作为初三学生也只有周末有空啊),每周一篇或两篇,没有按时发请往死里催我。。。
PS:文章内容属原创,如有雷同纯属偶然,部分引用或转载会说明出处,如侵权请联系删除(不要发账号,我不常登,邮箱:cdcos@outlook.com/cdcos@qq.com)
print("-"*40)
-------------------------------------------------------------------------------------- 二、代码实现废话少说,上正文:
今天的任务就是构建一个简单的函数,这个函数生成一个斐波那契数列。
2.1 简介首先介绍一下:
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)在现代物理、准晶体结构、化学等领域,斐波那契数列都有直接的应用,为此,美国数学会从 1963 年起出版了以《斐波那契数列季刊》为名的一份数学杂志,用于专门刊载这方面的研究成果。 (引自百度百科)
简单概括一下:1,1,1+1=2,1+2=3,2+3=5,3+5=8......
2.2 构思了解定义之后,首先构思一下如何写代码:定义开始的两项,后面每项等于前两项之和。还要增加一个判断条件,达到某个值就停止,不然停不下来了。
2.3 代码实现与剖析上代码:
def fib(n): #定义函数
"""Print a Fibonacci series up to 'n'.""" #文档字符串
a, b = 0, 1 #先定义第一,二项
while a< n: #判断是否满足条件
print(a, end=" ") #输出第一项
a, b = b, a + b #计算紧接着的下一项(前两项之和)
print() #输出数列
if __name__ == "__main__":
try:
foo = int(input()) #循环的大数值由用户决定
fib(foo) #调用函数
except: #当输入的不是整数时:
foo = int(input("Please input an integer!")) #打印提醒
fib(foo)
这是一个示例,如果有优化建议可以评论或者私信。
下面开始剖析这个函数:
2.3.1 def语句、命名规范以及为什么要使用函数def fib(n):
这是用来定义一个函数的语句,其中
def Function(parameter)
用来定义一个函数,Function为函数名。注意函数的命名应符合一定规范(你不符合也可以,但是这会使你的代码缺乏可读性,且会给他人阅读带来不便):
类:
总是使用首字母大写单词串。如MyClass。内部类可以使用额外的前导下划线。
函数&方法:
小写+下划线
注意:混合大小写仅被允许用于这种风格已经占据优势的时候,以便保持向后兼容。
函数和方法的参数(形参):
如果一个函数的参数名称和保留的关键字冲突,通常使用一个后缀下划线
全局变量
对于from M import *导入语句,如果想阻止导入模块内的全局变量可以使用旧有的规范,在全局变量上加一个前导的下划线。
注意:应避免使用全局变量
变量
小写,由下划线连接各个单词。如color = WHITE,this_is_a_variable = 1
大致概括了一下,这方面异议很多,所以并没有一个死的规范;比如你是Windows用户,那你的编程习惯会与Linux用户有很大不同。注意函数(方法)的命名除了上述规范,还应简洁且清晰地体现此函数的作用/功能。
为什么要使用函数?原因仅供参考:1、函数可以使一个大问题分化为多个小问题(化整为零),每个函数负责一个问题,再化零为整,组合起来。作者就尝试过不用函数编程,两个小时不是这里报错就是这里报错,几乎要了我的键盘的命(差点把键盘摔了);
2、使用函数能够避免一段代码的反复重用(即”DRY“,Don't repeat yourself),进而提高代码可读性与简洁程度。
2.3.2 关于形参与实参
“parameter”是参数(更准确地说,形参),用来向函数主体传递值(实参);
对形参和实参做一个简单的区分:形参就相当于一个标签,可以贴在不同的值上,后面的函数方法体可以通过此标签找到对应的值,所以说形参的作用就是传递值,真正传递的是形参所代表的实参。一个形参可以接受不同的值。
如果一头雾水,看这里:有一个停车位,编号为021(一个形参);停车场的主机里有一段程序,用伪代码描述:
def 控制停车位上的灯(停车位编号x):
if 编号为x停车位有车 == True:
亮对应编号为x的灯
形参x将实参"021"传入方法体,方法体根据实参的值执行相应的程序。编号并不只有"021"一个,因此形参x可以对应不同的值(实参)。
参数实际上就是变量,而变量的本质就是占位符,表示这里有个东西,至于是什么则等待一个值(对象)被赋给此变量。或者也可以理解为可以到处乱贴的标签,贴在某个对象(值)上就被赋予了该对象的意义。
如果还没有理解,也并不影响你编程,以后会慢慢理解的。
2.3.3 文档字符串
"""Print a Fibonacci series up to 'n'."""
这是可选的文档字符串(docstrings) ,由三个引号包裹,大概解释了此函数的作用/功能。如果有多行,第一行应该为简单的概括性描述,随后空一行,下接详细描述。多行的文档字符串格式如下:
"""................... #简单描述
#空一行
.......... #详细描述,可以有多行
...............................
..............................."""
在你的代码中包含文档字符串是一个好的实践,让它成为习惯吧。
2.3.4 简洁的赋值方式:a, b = 0, 1
a, b = 0, 1
a, b = 0, 1是Python特有的一种简洁的赋值方式,等效于a = 0, b = 1。
2.3.5 while循环与print函数
while a< n:
print(a, end=" ")
a, b = b, a + b
while引导一个循环,条件是判断斐波那契数列的结尾数字小于某个值(这里的某个值在下面定义)。
print() 函数将打印出圆括号内的值。end = ” “表示打印出的数列以空格隔开,如果不写则会分行打印。加引号或双引号表示打印字符串的内容。
a, b = b, a + b与上面是一样的。
2.3.6 try...except...语句,以及关于多态的简单介绍
if __name__ == "__main__":
try:
foo = int(input())
fib(foo)
except:
foo = int(input("Please input an integer!"))
fib(foo)
try....except...... 语句用于可能出现的错误。这里你无法确保用户输入的是一个整数,所以使用此语句可以避免报错。
try子句后跟可能报错的代码,如果不出错则只执行try子句,如果出错则跳到except子句。
int() 函数用于将某个值的类型转化为整数,如果交给int()函数的值不是整数就会报错。其实这里体现了Python与C语言不同之处,C需要在任一函数声明前限制输入类型,而Python则不需要,判断类型的任务交给后面的函数体执行。这就是所谓的”多态“。其实Python的多态不仅仅体现在这里,还体现在关于类的继承方面,这是后面的内容了。
input() 用于导入由用户决定的值(不单单指数字),括号内用于说明用户需要输入什么:
name = input("Please input your name.")
print("Your name is ", name)
#运行结果:
Please input your name.
Harry
Your name is Harry.
fib()实现了对函数fib的调用,即执行打印斐波那契数列的程序。
if __name__ == "__main__":这里就不赘述了,不然太长了。注意的地方就是有两个等号,Python中一个等号表示赋值(给变量),两个等号才是相等。下面有关于其解释:https://blog.csdn.net/sgzqc/article/details/124849467?spm=1001.2014.3001.5506
2.4 改进方案
剖析完毕。也许你会发现这里可以改进:此函数不返回值(实际上它返回None)。因此可以这样改进:
def fib(n): #定义函数
"""Return a list containing the Fibonacci series up to 'n'.""" #文档字符串
result = [] #创建接受返回值的列表
a, b = 0, 1 #对第一、二项赋值
while a< n: #条件
result.append(a) #向列表内加入值
a, b = b, a + b #计算数列
return result #返回值
if __name__ == "__main__":
try:
foo = int(input()) #确定循环的上限
fibfoo = fib(foo) #创建一个对象接受函数的返回值
print(fibfoo) #打印值
except: #当输入不是整数时:
foo = int(input("Please input an integer!")) #输出提醒
fibfoo = fib(foo)
print(fibfoo)
其中由于此时函数fib返回值,因此找了一个变量(也可以叫对象或者实例)来接受这个值,再用print语句打印出来。
result是一个列表,append是列表的一个方法,我们用点表示法来调用对象result下的一个方法append(result.append())。append方法用于向列表内加入值,且此值的位置在列表的最后(堆栈顶)。result = [] 用来定义一个空列表。列表还可以使用列表解析(列表推导式)。
2.5 其他的解法(关于递归)
也许你认为到此就结束了。不然。问一问自己是否还有其它解法?如果有,和上面的程序相比哪个运行效率高?
下面解法采用了递归的方式,不懂的可以自己查一查:
def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fib(n - 1) + fib(n - 2) #调用程序本身,即递归
if __name__ == "__main__":
f = fib(10) #调用函数
print(f)
这个例子不是打印出数列,而是打印出n=10时数列的值。
解析:假设n=3:
1.n=3,fib(3),走return fib(n - 1) + fib(n - 2)分支;
2.fib(3-1),即fib(2),也走else分支,计算fib(2-1)+fib(2-2);
3.fib(2-1)即fib(1),走elif 分支,返回1,fib(2-2)返回0,即fib(3-1)=1+0=1;
4.再计算fib(3-2)=1;
5.fib(3-1)+fib(3-2)=1+1=2,即返回值为2(fib(3)=2)。
比较一下两者运行的时间(可以用time模块中的clock()函数,用来计算程序运行时间的。注意Python3.8往后已经没有此函数,可以用
time.process_time()
代替)。可以发现,示例一是0.046875秒,示例二是0.0625秒(循环上限均取10且示例一没有执行except 子句),效率差别很明显了。
下周见!
PS. 示例二的代码引自《跟老齐学Python——从入门到精通》,如有侵权请联系删除,邮箱:cdcos@outlook.com/cdcos@qq.com。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网站栏目:100周Python进阶:第一周:构建一个简单的斐波那契数列函数-创新互联
文章分享:http://ybzwz.com/article/djpcoj.html