4. Python 编写函数#
用 Python 编写函数时,经常要用到条件语句if
, 循环语句for
或while
。
4.1. 条件语句#
if
语句的字面意思是:如果(if)满足条件,做什么,否则(else)做什么。例如,下面一段代码:
a = 10
if a > 10:
print("Value of a is greater than 10")
else:
print("Value of a is not greater than 10")
Value of a is not greater than 10
这段代码的意思是,如果 a 比 10 大,则输出 “Value of a is greater than 10”,否则输出 “Value of a is not greater than 10”。if 语句还可以跟 elif (else if 的意思),再次判断一个条件。
if 语句的一般用法 |
---|
if <条件1>: |
<statement_block_1> |
elif <条件2>: |
<statement_block_2> |
else: |
<statement_block_3> |
Note
if 循环中,elif
语句块或者else
语句块可以没有
上面 if 语句块的执行顺序为:如果条件1 为真,将执行 “statement_block_1” 块语句,如果条件1 为假,将判断 “条件2”,如果条件2 为真,将执行 “statement_block_2” 块语句,如果条件2 为假,将执行”statement_block_3”块语句。
举例:
wage = 5000
print("")
if wage <= 3000:
print("贫困户")
elif wage <= 12000:
print("平均水平")
else:
print("土豪")
平均水平
上面语句的意思是,若输入的月薪小于 3000,则输出“贫困户”,否则若月薪在 3000 与 12000 之间,输出“平均水平”,若月薪在 12000 之上,则输出“土豪”。
if 语句里面还可以嵌套 if 语句,进一步增加判断条件,举例:
wage = 2000
print("")
if wage <= 3000:
print("贫困户")
if 2000 <= wage < 3000:
print("贫困户中的一般贫")
if wage <= 1000:
print("贫困户中的特贫")
else:
print("不是贫困户")
贫困户
贫困户中的一般贫
在上面的程序中,若月薪小于等于 3000,又嵌套了两个条件进一步判断。
if 中条件判断中常用的符号有:>
(大于), <
(小于), >=
(大于等于), <=
(小于等于), ==
(等于), !=
(不等于)。
Note
两个等号 == 表示判断是否相等(a == 3 表示判断 a 是否等于 3),而一个等号 = 表示的是变量赋值(a = 3 表示将 a 赋值为 3)
4.2. 循环语句#
循环语句一般有两种,for 语句与 while 语句。for 循环可以遍历任何序列的项目,如一个列表、元组、集合或者一个字符串。for 循环的一般用法如下:
for 循环语句的一般用法 |
---|
for <variable> in <sequence>: |
<statements> |
for 循环的作用是:遍历序列(sequence)中的所有元素,执行命令语句 statements,举例:
for i in range(3):
print(i)
0
1
2
输出结果为 0, 1, 2,上述代码的作用是,对于 range(3) 中的每一个元素,打印元素。for 循环经常结合序列函数 range() 一起使用:range(a) 表示从 0 到 a-1 的一个数列,range(a, b) 表示从 a 到 b-1 的一个数列,range(a, b, c) 表示从 a 到 b-1,步长为 c 的一个数列。
若索引 i 在循环中的命令语句中不使用,可以用_
代替。
for _ in range(3):
print("Hello, World!")
Hello, World!
Hello, World!
Hello, World!
Note
for 循环或 while 循环都可以跟else
语句,else
语句只在循环正常执行并结束后才执行。
另一个 while 循环语句的一般格式为:
while 循环语句的一般用法 |
---|
while <判断条件>: |
<statements> |
它的作用是,只要满足 while 的判断条件,则一直执行 while 下面的执行语句 statements。
举例:
a = 1
while a < 4:
print(a)
a = a + 1
1
2
3
上面语句的作用是:只要 a 小于 4,则将 a 值打印出来并将 a 值加 1,在 a 等于 4 时停止执行 while语句。
for 循环与 while 循环经常结合break
或continue
语句,break
语句可以跳出循环体,而continue
语句用来告诉 Python 跳过当前循环中的剩余语句,然后继续进行下一轮循环。举例:
for i in range(3):
if i == 1:
break
print(i)
print("循环结束")
0
循环结束
上面代码中,在 i 等于 1 时执行break
跳出了整个循环体。
若改为continue
语句:
for i in range(3):
if i == 1:
continue
print(i)
print("循环结束")
0
2
循环结束
上面代码中,在 i 等于 1 时执行continue
跳出了当前循环,执行剩下的循环。
在 while 循环中,break
与continue
的例子:
a = 1
while a < 5:
a = a + 1
if a == 3:
break
print(a)
print("循环结束")
2
循环结束
a = 1
while a < 5:
a = a + 1
if a == 3:
continue
print(a)
print("循环结束")
2
4
5
循环结束
4.3. 自定义函数#
Python 提供了许多内建函数,比如 print(),但也可以自己创建函数,这被叫做用户自定义函数。掌握了自定义函数后,就能用 Python 实现很多自己想要的功能了。Python 自定义函数使用def
关键字,一般用法如下:
def 自定义函数的一般用法 |
---|
def <函数名>(<参数列表>): |
<statements> |
下面的几行代码定义了一个加和函数:
def add(x1, x2):
z = x1 + x2
return z
该自定义函数有以下几个特点:
def | 关键字 def 开头 |
add | 函数的名字,可以自命名 |
(x1, x2) | 小括号里面是函数的输入参数 |
: | 冒号,换行写函数内容;若不换行,整个函数只能有一行代码 |
return | 关键字,后面跟函数的返回值,即输出结果 |
函数的返回值可以有一个或多个,下面的代码返回多个值,既返回两个参数的加和结果,又返回两个参数的值。
def add(x1, x2):
z = x1 + x2
return z, x1, x2
调用函数时,通过输入函数名字,并把函数的参数传递进去,例如:
def add(x1, x2):
z = x1 + x2
return z
x1 = 10
x2 = 6
print(add(x1, x2))
16
若某个返回值不使用,可以用下划线_
替代该变量名。
def add(x1, x2):
z = x1 + x2
return z, x1, x2
x1 = 10
x2 = 6
sums, _, b = add(x1, x2) # 用下划线 _ 替代第二个返回值
print(sums)
print(b)
16
6
上面的代码中,用下划线替代第二个返回参数值,用新的变量名替代其他参数值。
函数也可以不带输入参数,即小括号里面可以没有内容,例如,下面的代码打印一句话 ``Hello, world!”:
def hello():
print("Hello, world!")
hello()
Hello, world!
可以利用三重引号,来添加函数的说明 (docstring),例如:
def hello():
"""This is a hello function."""
print("Hello, world!")
hello()
Hello, world!
在一些 python IDE 软件中,例如 Spyder 或 Pycharm,当鼠标停留在某个函数或类名时,自动显示该函数或类的说明(docstring),极大地增加了代码的可读性。
4.3.1. 函数参数的传递类型#
根据输入参数的值是否可以改变,函数的参数传递类型包括以下两种:
不可变类型:数字,字符串,元组
可变类型:列表,字典,集合
对于不可变类型,函数调用参数后,参数原来的值不变,例如:
def changeNum(a):
a = 10
b = 2
changeNum(b)
print(b) # 结果还是 2
2
上面的代码中,由于传递的是数字类型,调用函数后,参数原来的数值不变,对于字符串或元组类型,传递时也是这样。
对于可变类型,函数调用参数后,参数原来的值也改变,例如:
def changeList(mylist):
mylist.extend([1, 2, 3])
return mylist
listTry = [10, 20, 30]
changeList(listTry)
print(listTry) # 结果是 [10, 20, 30, 1, 2, 3],改变了列表原来的值
[10, 20, 30, 1, 2, 3]
4.3.2. 函数的参数传入方法#
函数的参数传入方法主要有4种类型:
顺序传入
赋值传入
默认参数值传入
不定长参数传入
对于顺序传入,函数的参数值跟输入的顺序一一对应:
def minus(x1, x2):
z = x1 - x2
return z
print(minus(10, 6))
4
在上面的代码中,调用 minus 函数,按照参数的顺序,认为 x1 的值为 10, x2 的值为 6。
赋值传入的意思是:在调用函数时,可以在输入参数时直接给参数赋值,Python 自动根据括号内的参数名匹配参数值,例如:
def minus(x1, x2):
z = x1 - x2
return z
print(minus(x2=10, x1=6))
-4
在上面的代码中,调用 minus 函数时,在小括号内对参数进行了赋值,认为 x2 的值为 10, x1 的值为 6。
Python 在定义函数时,可以设置参数的默认值,当调用参数时,若没有给参数赋值,则使用参数的默认值,例如:
def minus(x1, x2=6):
z = x1 - x2
return z
print(minus(x1=10)) # 输出:4,没有传递参数值时默认参数值
print(minus(x1=10, x2=5)) # 输出:5,有传递参数值时,覆盖默认参数值
4
5
当一个函数传递多个参数,但不太确定究竟是多少个时,可以用 *args 表示多个参数,例如:
def plus(x, *args):
print("x is %d" % x)
for var in args:
x += var
print("final x is %d" % x)
plus(3, 4, 5) # *args 是 4, 5
plus(3, 4, 5, 6) # *args 是 4, 5, 6
x is 3
final x is 12
x is 3
final x is 18
可以用 **args 来传递不定长的多个赋值的参数,例如:
def minus(x1, **args):
sum = 0
for key in args:
sum += args[key]
return x1 - sum
print(minus(10, x2=3, x3=5))
7
上面的代码中,用 **args 表示 x2 = 3, x3 = 5。
4.4. 调试程序#
调试程序是编程不可避免的步骤,调试就是为了帮组发现与修改程序中的错误。因为即使再优秀的程序员,也不可能在编写一个新的程序时一点错误也没有。调试程序有以下几种常用的方法。
4.4.1. 使用 print() 进行简单调试#
这种调试方法适用于:代码短,问题简单,只需要查看几个变量的值的情况。一般是在怀疑可能会出错的代码行前面使用print()
语句打印出一些变量值或函数输出结果,从而帮助程序员判断哪里出错。
例如,下面的例子中在可能发生错误的前一行使用 print 语句输出变量 a 与 b 的值。
def divide(a, b):
print(f"DEBUG: a={a}, b={b}") # 调试信息
return a / b # 可能发生 ZeroDivisionError
print(divide(10, 2))
print(divide(5, 0)) # 这里会出错
这种方法的缺点是:每次都要手动修改 print() 位置;不能暂停代码,调试麻烦。
4.4.2. 使用调试器调试#
Python 自带一个调试器 pdb
,其他的 Python 编程软件(IDE)Spyder, Pycharm, VS code 等在菜单栏或工具栏也有专门的调试功能。
调试器调试的一般步骤是:
在怀疑出错的代码行前面设置断点
IDE软件是在代码行号处单击(会出现红点)
pdb为添加一行代码 pdb.set_trace()
启动调试
使用调试功能,发现或修改错误
退出调试
下面代码为使用 pdb 进行调试的例子:
import pdb
def divide(a, b):
pdb.set_trace() # 进入调试模式
return a / b
print(divide(10, 2))
运行代码后,会出现一个 pdb 的命令行,我们可以在命令后输入命令进行调试。
pdb 常用命令:
命令 |
作用 |
---|---|
n (next) |
执行当前行,不进入函数 |
s (step) |
进入函数内部 |
r (return) |
运行到当前函数结束 |
p var |
打印变量值 |
c (continue) |
继续运行到下一个断点 |
q |
退出调试 |
4.4.3. 调试功能的 step into, step over, step out, resume program#
使用 IDE 软件调试时,step into
、step over
、step out
和 resume program
是调试器的常见功能,它们的区别如下:
Step Into(进入函数):逐行执行代码,并且如果当前行有函数调用,就进入该函数内部。
相当于 pdb 中的
s
Step Over(跳过函数):执行当前行的代码,但如果当前行有函数调用,则不进入该函数,而是直接执行完该行,停在下一行。
相当于 pdb 中的
n
Step Out(跳出函数):如果在函数内部,执行完当前函数的剩余代码,并返回到调用该函数的位置;如果在函数外部,则继续执行程序,直到下一个断点或程序结束
相当于 pdb 中的
r
resume program:继续执行程序,直到下一个断点或程序结束。
相当于 pdb 中的
c
def add(a, b):
return a + b
def main():
x = 10
y = 20
result = add(x, y) # 如果在这里 "Step Into",会进入 add 函数
print(result)
main()
30
在 result = add(x, y) 这一行 Step Into,会进入 add 函数的第一行,逐行执行 add 的代码。
def add(a, b):
return a + b
def main():
x = 10
y = 20
result = add(x, y) # 如果在这里 "Step Over",不会进入 add,直接执行并跳到 print(result)
print(result)
main()
30
在 result = add(x, y) 这一行 Step Over,不会进入 add 函数,而是直接执行完 add,然后跳到 print(result)。
import pdb
def add(a, b):
return a + b # 如果在这里 "Step Out",会直接执行 return 并返回到 main() 的调用处
def main():
x = 10
y = 20
result = add(x, y)
print(result)
main()
30
如果调试器当前在 return a + b 这一行,使用 Step Out,会执行 return a + b 并直接回到 result = add(x, y) 这一行。
在一些调试器中(例如 Pycharm),Step Into My Code
是一个增强版的 Step Into,它的作用是:
进入你自己编写的代码,而跳过 Python 内置库、第三方库的代码。
避免进入外部库(如 numpy, pandas 等),只调试自己写的部分,提高调试效率。
Note
Spyder 软件的调试功能命令与上面所讲的命令略有不同,但比较类似。
4.5. try-except 语句调试#
在编写程序时,有时候不知道程序能否正确运行,想试试程序运行结果如何,可以使用 try-except语句;若 try 块中的语句无法执行通过,则执行 except 块中的语句。
try-excpet 语句的一般用法 |
---|
try: |
<语句块1> |
except [异常类型]: |
<语句块2> |
这个语句在程序调试时经常使用,下面的代码定义了一个除法函数:
def devide(x1, x2):
try:
z = x1 / x2
print(z)
except ZeroDivisionError: # ZeroDivisionError 表示试图除以零时发生的错误
print("x2 should not be zero")
devide(5, 0)
x2 should not be zero
上面的代码中,若 x1 能除以 x2,则输出除法结果,否则提示 x2 不能为零。
Python 还有一个关键字pass
,不执行任何命令。一般用做占位语句,在程序调试时可以使用。
def devide(x1, x2):
try:
z = x1 / x2
print(z)
except:
pass
devide(5, 0)
上面的代码中,若 x1 能除以 x2,则输出除法结果,否则程序不输出任何结果。
常见的异常类型还有:
异常类型 |
描述 |
---|---|
AttributeError |
访问对象不存在的属性或方法 |
IndexError |
访问超出列表范围的索引 |
SyntaxError |
语法错误 |
NameError |
访问未定义的变量或函数时发生的错误 |
TypeError |
调用函数时,传递参数的类型错误 |
ModuleNotFoundError |
导入不存在的模块或找不到模块 |
ValueError |
函数参数的数据类型正确,但值不符合要求 |
4.6. 导入其他模块(module)#
Python 编程中,每个以 .py 为后缀的文件被称作模块(module)。很多时候,我们需要导入其他模块中的函数,
在 Python 中导入其他文件夹中的模块时,有几个规则和方法可供使用。主要涉及 Python 的模块搜索路径(sys.path),以及如何使用相对导入和绝对导入。
4.6.1. Python 如何查找模块#
当前目录(脚本所在的文件夹)。
sys.path
中的目录:PYTHONPATH
环境变量中的路径。Python 安装目录中的标准库路径。
site-packages
目录(安装的第三方库)。
你可以运行以下代码查看 Python sys.path中的路径目录:
import sys
print(sys.path)
['/Users/zhenchen/Documents/book-Python-Data-Science-cn/data-science-cn', '/Users/yourname/projects', '/Users/zhenchen/Documents/book-Python-Data-Science-cn/data-science-cn', '/opt/anaconda3/lib/python312.zip', '/opt/anaconda3/lib/python3.12', '/opt/anaconda3/lib/python3.12/lib-dynload', '', '/opt/anaconda3/lib/python3.12/site-packages', '/opt/anaconda3/lib/python3.12/site-packages/aeosa', '/opt/anaconda3/lib/python3.12/site-packages/setuptools/_vendor']
4.6.2. 同级模块导入或同级文件夹下的模块导入#
若导入模块是当前模块的同级文件,即二者在一个父目录下,例如:
目录结构
project_root/
│── main.py
│── my_module.py
我们在 main.py 文件中想导入 my_module.py 模块,可以:
import my_module
若具体想导入 my_module.py 模块中的某个函数或类 foo(),可以
from my_module import foo
若导入模块在与当前模块同级的文件夹下,例如:
目录结构
project_root/
│── main.py
│── folder1/
│ │── my_module.py
我们在 main.py 文件中想导入 folder1 文件夹下的 my_module.py 模块,可以:
from folder1.my_module import foo
4.6.3. 与父文件夹同级的模块导入#
若导入模块在与当前模块父文件夹同级,例如:
目录结构1
project_root/
│── my_module.py
│── folder1/
│ │── main.py
或者:
目录结构2
project_root/
│── folder2
│ │── my_module.py
│── folder1/
│ │── main.py
在 main.py 文件中想导入与父文件夹同级的 my_module.py 模块,可以通过将父文件夹路径添加到 sys.path 中去的方式:
import sys
import os
# 获取 `parent_directory` 路径
parent_dir = os.path.abspath(os.path.join(os.getcwd(), "..")) # .. represents the parent directory
sys.path.insert(0, parent_dir) # 插入 `parent_directory` 到 sys.path
现在可以正确导入 my_module.py
若为目录结构1: import my_module
若为目录结构2: from folder2 import my_module
Note
Pycharm 会自动把整个项目文件夹的根目录加入到 sys.path 中,因此在 Pycharm 中,都可按照跟目录下的模块导入
例如,在 Pycharm 中,对于目录结构2,可以直接按下面代码导入模块,而不用通过 sys.path 添加父文件夹路径。
from folder2 import my_module
4.6.4. 使用 sys.path.append()
#
如果你的模块所在路径比较复杂,你可以使用以下方法 sys.path.append()
添加导入模块的具体路径。
例如,如果你想导入 other_folder/module.py
,其中,”other_folder” 为文件夹在电脑硬盘中的详细地址。可以在代码中手动添加路径:
import sys
import os
sys.path.append(os.path.abspath("other_folder")) # 临时将路径添加到 sys.path
import module # 现在可以正常导入
4.7. lambda, map, filter, reduce 函数#
Python 使用lambda
来创建匿名函数。所谓匿名,即不再使用 def 语句这样标准的形式定义一个函数。lambda 函数只有一行,用一个冒号分割传递参数与函数的返回值。非常简洁,在 Pandas 处理数据时经常结合 apply 函数使用。
lambda 函数的一般用法 |
---|
<函数名> = lambda <参数列表>: <表达式> |
add = lambda x1, x2: x1 + x2
print(add(10, 6))
16
也可以结合 if-else 语句定义 lambda 函数。
Max = lambda a, b: a if a > b else b
print(Max(12, 20))
20
map(fun, iter)
对每一个可迭代对象 iter 中的元素应用 fun 函数,并返回一个 map 类型的可迭代对象。fun 函数既可以使用 lambda 匿名函数,也可以用 def 自定义一个函数。
a = [1, 2, 3]
b = map(lambda x: x**2, a) # 对 a 中每个元素平方
b
<map at 0x10840c250>
可以用list()
函数将这个可迭代对象转化为 list 类型:
list(b)
[1, 4, 9]
filter(fun, iter)
对可迭代对象 iter 中的每一个元素应用判断函数 fun 过滤,并返回一个 filter 类型的可迭代对象。
a = [1, 2, 3]
b = filter(lambda x: x >= 2, a) # 将大于等于 2 的元素过滤出来
list(b)
[2, 3]
reduce(fun, iter)
首先对可迭代对象 iter 中的前两个元素应用函数 fun,然后将其结果作为 fun 的第一个输入值,再对第 3 个元素应用 fun 函数;以此类推,最后返回一个数。使用 reduce 函数需要从工具包 functools 中提前导入。
from functools import reduce # 从工具包 functools 中导入 reduce
a = [1, 2, 3, 4]
b = reduce(lambda x1, x2: x1 + x2, a) # 求和
b
10
reduce
也可以跟 3 个参数,即reduce(fun, iter, start=None)
。此时,首先对一个初始值 start 与可迭代对象 iter 中的第一个元素应用函数 fun,然后将其结果作为 fun 的第一个输入值,再对第 2 个元素应用 fun 函数;以此类推,最后返回一个数。
a = [1, 2, 3, 4]
b = reduce(lambda x1, x2: x1 + x2, a, 10) # 求和,起始值为 10
b
20
4.8. 一些常用的内置函数#
Python 内置了一些常用的函数,可以方便使用。本书简单介绍以下几个内置函数:
函数 |
功能描述 |
---|---|
sum |
对可迭代对象(如列表,元组,集合)求和 |
max |
返回可迭代对象中的最大值 |
min |
返回可迭代对象中的最小值 |
abs |
返回输入数值的绝对值 |
round |
返回输入数值的四舍五入值 |
range |
创建一个整数序列类型,多用于 for 循环 |
sorted |
对可迭代对象进行排序,默认升序 |
round(3.1415926, 2) # 四舍五入时保留两位小数
3.14
round(3.1415926) # 默认四舍五入为整数
3
range 被 Python 直接视为一种数据类型,表示一个整数数列。包含终点(必有),起点(可选),步长(可选)。可以用list()
将 range 类型转化为列表类型。
range(10) # 创建一个从 0 到 10 (不包括 10) 的整数序列,默认起点为 0,默认步长值为 1
range(0, 10)
list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
range(2, 10) # 创建一个从 2 到 10 的整数序列
range(2, 10)
range(2, 10, 2) # 创建一个从 2 到 10 的整数序列,并且步长值为 2
range(2, 10, 2)
list(range(2, 10, 2))
[2, 4, 6, 8]
eumerate 经常结合 for 循环使用。
a = [20, 30, 40, 50]
for i in range(len(a)):
print(a[i], i)
20 0
30 1
40 2
50 3
使用 enumerate 则上述代码更简洁些:
a = [20, 30, 40, 50]
for item, i in enumerate(a):
print(item, i)
0 20
1 30
2 40
3 50
sorted 函数可以对可迭代对象进行排序,默认为升序,可迭代对象一般是列表。
arr = [23, 54, 12, 37]
sorted(arr) # 对列表升序排列
[12, 23, 37, 54]
sorted(arr, reverse=True) # 对列表降序排列
[54, 37, 23, 12]
4.9. 练习#
Exercise 4.1
判断用户输入的年份是否为闰年。
Solution to Exercise 4.1
year = int(input("输入一个年份: "))
if (year % 4) == 0:
if (year % 100) == 0:
if (year % 400) == 0:
print("{0} 是闰年".format(year)) # 整百年能被400整除的是闰年
else:
print("{0} 不是闰年".format(year))
else:
print("{0} 是闰年".format(year)) # 非整百年能被4整除的为闰年
else:
print("{0} 不是闰年".format(year))
Exercise 4.2
编写一个程序,打印出九九乘法表。
Solution to Exercise 4.2
for i in range(1, 10):
for j in range(1, i + 1):
print('{}*{}={}\t'.format(j, i, i*j), end='')
print()
Exercise 4.3
自定义一个函数,给定数值 \(n\),能够计算 从 1 到 \(n\) 所有自然数的立方和。
Solution to Exercise 4.3
def sumOfCube(n):
sum = 0
for i in range(1, n+1):
sum += i * i *i
return sum
# 调用函数
n = 10
print(sumOfCube(n))
Exercise 4.4
从键盘输入两个整数,编写一个程序可以求出这两个整数的最大公约数。
Solution to Exercise 4.4
# 定义一个函数
def gcd(x, y):
gcd = 1 # 初始值为 1
# 获取两个数的最小值
if x > y:
smaller = y
else:
smaller = x
for i in range(1, smaller + 1):
if (x % i == 0) and (y % i == 0):
gcd = i
return gcd
# 用户输入两个数字
num1 = int(input("输入第一个数字: "))
num2 = int(input("输入第二个数字: "))
print(num1, "和", num2, "的最大公约数为", gcd(num1, num2))
Exercise 4.5
输出指定数目的斐波那契数列。
Solution to Exercise 4.5
# 获取用户输入数据
nterms = int(input("the number of sequence:"))
# 第一和第二项
n1 = 0
n2 = 1
count = 2
# 判断输入的值是否合法
if nterms <= 0:
print("please input a positive value")
elif nterms == 1:
print("斐波那契数列:")
print(n1)
else:
print("斐波那契数列:")
print(n1, end=", ")
print(n2, end=", ")
while count < nterms - 1:
nth = n1 + n2
print(nth, end=", ")
# 更新值
n1 = n2
n2 = nth
count += 1
nth = n1 + n2
print(nth)
Solution to Exercise 4.5
def recur_fibo(n):
"""
递归函数
输出斐波那契数列
"""
if n <= 1:
return n
else:
return recur_fibo(n - 1) + recur_fibo(n - 2)
# 获取用户输入
nterms = int(input("您要输出几项? "))
# 检查输入的数字是否正确
if nterms <= 0:
print("输入正数")
else:
print("斐波那契数列:")
for i in range(nterms):
print(recur_fibo(i))
Exercise 4.6
输出指定范围内的素数。
Solution to Exercise 4.6
# take input from the user
lower = int(input("输入区间最小值: "))
upper = int(input("输入区间最大值: "))
for num in range(lower, upper + 1):
# 素数大于 1
if num > 1:
for i in range(2,num):
if (num % i) == 0:
break
else:
print(num)
Exercise 4.7
编写一个程序,能够得到昨天的日期。(提示:使用 datatime 库)
Solution to Exercise 4.6
import datetime
def getYesterday():
today = datetime.date.today()
oneday = datetime.timedelta(days = 1)
yesterday = today - oneday
return yesterday
# 输出
print(getYesterday())
Exercise 4.8
编写一个程序,实现秒表功能。(提示:使用 time 库)
Solution to Exercise 4.8
import time
print("按下回车开始计时,按下任意键停止计时。")
while True:
input("")
starttime = time.time()
print("开始")
try:
while True:
print("计时: ", round(time.time() - starttime, 0), "s")
time.sleep(1)
except KeyboardInterrupt:
print("结束")
endtime = time.time()
print("总共的时间为:", round(endtime - starttime, 2), "s")
break