一、递归函数
递归函数可以在函数主体内直接或间接的调用自己,即函数的嵌套时函数本身。递归是一种程序设计方法,使用递归可以减少重复的代码,使程序变得简洁。递归的过程分为两个阶段——递推和回归。递归函数的原理如下:
第一阶段,递归函数在内部调用自己。每一次函数调用又重新开始执行此函数代码,直到某一级递归程序结束。
第二阶段,递归函数从后往前返回。递归函数从最后一级开始返回,一直返回到第一次调用的函数体内。即递归逐级调用完毕后,再按照相反的顺序主机返回。
递归函数需要编写递归结束条件;否则,递归程序将无法结束。一般通过判断语句来结束程序。
练习(是用递归实现阶乘):
#用递归实现1-6的阶乘
def mul(n):
if(n>1):
return n*mul(n-1)
else:
return 1
result = mul(6)
print(result)
注意:每次调用递归函数都会复制函数中所有变量,再执行递归函数。程序需要较多的存储空间,对程序性能会有一定影响。因此,对于没有必要进行的递归程序,最好用其他的方法进行改进
递归程序在实现时依靠栈这种数据类型,在递推过程中,调用自己之前将当前环境变量当前数据压入栈内,递推到最后返回时,逐级将栈中数据弹出,这样就是实现的递归过程中的存储。
可以使用reduce()函数快速实现阶乘的运算
from functools import reduce
print("5!=",reduce(lambda x,y:x*y,range(1,6)))
二、匿名函数
lambda函数用于创建一个匿名函数,函数名未知标识符进行绑定。使用lambda函数可以返回一些简单的运算结果。lambda函数的格式如下所示:
lambda 变量2,变量2...:表达式
其中,变量列表用于表达式计算。lambda属于函数,因此变量列表后需要一个冒号。通常把lambda赋值给一个变量,变量就可以作为函数使用。例如:
func = lambda 变量1,变量2...:表达式
func()
这样就把lambda和变量func绑定在一起了,变量func的名称就是函数名。注意,lambda中只能使用表达式,不能使用判断、循环等多重语句。
三、文件
程序在运行过程当中,数据都在内存中,在下次运行程序时,之前的数据不会被保存下来,如需保存程序运行时的数据,则需要引入文件对程序数据进行保存。
数据的存储可以使用数据库,也可以使用文件。数据库保持了数据的完整性和关联性,而且使数据更安全、可靠。使用文件存储数据则非常简单、易用,不必安装数据库管理系统等运行环境。文件通常用于存储应用软件的参数或临时性数据。
1.文件的常见操作
文件通常用于存储数据或应用系统的参数。python提供了os、os.path、shutil等模块处理文件,其中包括打开文件、读写文件、复制文件和删除文件等函数。
1.1文件的创建
文件的打开或创建可以使用open()函数,该函数可以指定处理模式。
文件的打开模式:
- r 以只读的方式打开文件
- r+ 以读写的方式打开文件
- w 以写入的方式打开文件。先删除文件原有的内容,再重新写入新的内容。如果文件不存在,则创建1个新的文件。
- w+以读写的方式打开文件。先删除文件原有的内容,再重新写入新的内容。如果文件不存在,则创建1个新的文件。
- a 以写入的方式打开文件,在文件的末尾追加新的内容。如果文件不存在,则创建一个新的文件。
- a+ 以读写的方式打开文件,在文件的末尾追加新的内容。如果文件不存在,则创建一个新的文件。
- b 以二进制模式打开文件。可与r、w、a、+结合
注意,对于图片、视频等文件必须使用“b”的模式读写。
1.2.file类的常用属性和方法
(1)close() 关闭文件
(2)read([size]) 从文件中读取size个字节的内容,作为字符串返回
(3)readline([size]) 从文件中读取一行,作为字符串返回。如果指定size,表示每行每次读取的字节数,依然要读完整行的内容。
(4)readlines([size]) 把文件中的每行存储在列表中返回。如果指定size,表示每次读取的字节数。
(5)seek(offset[,whence]) 把文件的指针移动到一个新的位置。offset表示相对于whence的位置。whence用于设置相对位置的起点,0表示从文件的开头开始计算;1表示从当前位置开始计算;2表示从文件末未开始计算。如果,whence省略,offset表示相对文件开头的位置。
(6)tell() 返回文件指针的当前位置。
(7)write(str) 把字符串str的内容写入文件。
1.3.文件的处理一般分为3个步骤:
(1)创建并打开文件,使用file()函数返回个file对象。
(2)调用file对象的read()、write()等处理文件。
(3)调用close()关闭文件,释放file对象占用的资源。
close()方法是必要的,虽然python提供了垃圾回收机制,清理不再使用对象,但是手动释放不再需要的资源是一种良好的习惯。同时也显示地告诉python垃圾回收器,该对象需要被删除。
1.4.文件的读取
(1)按行读取方式readline()
readline()每次读取文件中的一行,需要使用永真表达式循环读取文件。但当文件指针移动到文件的末尾时,依然使用radline()读取文件将会出现错误。因此程序中需要添加1个判断语句,判断文件指针是否移动到文件的尾部,并通过该语句中断循环。
f = open("test.txt")
while True:
line = f.readline()
if line:
print(line)
else:
break
f.close()
(2)多行读取方式readlines()
使用readlines()读取文件,需要通过循环访问readlines返回列表中的元素。函数readlines()可一次性读取文件中的多行数据。
(3)一次性读取方式read()
读取文件最简单的方法是使用read(),read()将从文件中一次性读出所有内容,并赋值给一个字符串变量。
1.5.文件的写入
文件的写入使用write()方法
1.6.文件的重命名
os模块的函数rename()可以对文件或目录进行重命名。
练习(文件重命名):
#f.tell()表示文件指针的当前位置
#f.seek(a,b)文件的随机读写b=0/1/2,0表示文件开头,1表示当前位置,2表示文件结尾,a表示从指定位置出向后定位a位
#文件批量重命名
import os
#提示用户输入要重名的文件名
need_rename = input("请输入要重命名的文件名")
all_file_name = os.listdir("./"+need_rename)
print(all_file_name)
for file_name in all_file_name:
find_pos = file_name.rfind(".")
new_name = file_name[:find_pos]+"new"+file_name[find_pos:]
print(new_name)
os.rename("./"+need_rename+"/"+file_name,"./"+need_rename+"/"+new_name)#重命名时一定要注意文件的路径
print("重命名成功!")
new_file_name = os.listdir("./test")
练习(删除文件名前缀):
import os
need_rename = input("请输入要删除前缀的文件名:")
need_renames = os.listdir("./"+need_rename)
remain_name = input("请输入要保留的第一个字:")
for name in need_renames:
del_prio_name = name.rfind(remain_name)
new_name = name[del_prio_name:]
os.rename("./"+need_rename+"/"+name,"./"+need_rename+"/"+new_name)
new_list = os.listdir("./"+need_rename)
print(new_list)
四、练习
练习一(实现文件复制并重命名):
#文件复制
#提示用户要复制的文件名
name = input("请输入要读取的文件名:")
#打开文件1
f1 = open(name,"r")
#找到文件名中.的位置
post_pos = name.rfind(".")
#创建新的文件名
new_name =name[:post_pos]+"[复制]"+name[post_pos:]
print(new_name)
#打开文件2
f2 = open(new_name,"w")
#方式1
#存储文件1内容
#str_of_f1 = f1.read()
#将文件1读出的内容写入文件2
#f2.write(str_of_f1)
#方式2
#文件1按行读取,再写入文件2中
#for content in f1.readlines():
# f2.write(content)
#方式3
while(True):
str = f1.readline()
if (len(str)):#判断读取出的内容是否为空
f2.write(str)
else:
break
print("文件读写完毕!!")
#关闭文件1和文件2
f1.close()
f2.close()
#读取并输出复制文件的内容
f=open(new_name,"r")
print("复制的文件名为",new_name)
print("内容为:")
print(f.read())
f.close()
练习2(实现学生管理系统的数据文件保存):
#学生信息管理系统
names = []
#打印输出界面信息
def print_info():
print("=" * 30)
print("1:添加学生信息")
print("2:删除学生信息")
print("3:修改学生信息")
print("4:查询学生信息")
print("5:保存学生信息")
print("0:退出系统")
print("=" * 30)
#获取键入的学生信息
def get_infor():
new_name = input("请输入学生的名字:")
new_sex = input("请输入学生的性别:")
new_high = input("请输入学生的身高:")
return {"name":new_name,"sex":new_sex,"high":new_high}
#添加学生信息
def add_info():
result = get_infor()
student_info = {}
student_info["name"] = result["name"]
student_info["sex"] = result["sex"]
student_info["high"] = result["high"]
names.append(student_info)
print("添加成功!")
#删除学生信息
def del_info():
name = input("请输入要删除的学生姓名:")
for name_check in names:
if (name_check["name"] == name):
names.remove(name_check)
break
print(names)
print("删除成功!")
#修改学生信息
def update_info():
result = get_infor()
for name_check in names:
if (name_check["name"] == result["name"]):
break
name_check["name"] = result["name"]
name_check["sex"] = result["sex"]
name_check["high"] = result["high"]
print("修改成功!")
#查询学生信息
def check_info():
name = input("请输入要查询的名字:")
for name_check in names:
if (name_check["name"] == name):
flag = 1
break
if (flag == 1):
print("查找成功!")
print(" 姓名 性别 身高")
print(" %s %s %s" % (name_check["name"], name_check["sex"], name_check["high"]))
#保存文件信息
def save_file():
f = open("student.data","w")
f.write(str(names))
f.close()
# f = open("student.data", "r")
# content = f.read()
# list = eval(content)#将读出的文件字符串转换为其数据本来的类型
# print(list)
#恢复数据
def recover_data():
global names#全局变量在函数中使用时为了避免不必要的bug,一定在使用全局变量的时候用global关键字声明
f = open("student.data","r")
content = f.read()
names = eval(content)
f.close()
def main():
#恢复数据
recover_data()
print(names)
#系统提示
while(True):
print_info()
#获取操作数字
op = input("请输入你要进行的操作:")
#根据用户选择进行功能调用
flag = 0
if(op == "1"):
add_info()
elif(op == "2"):
del_info()
elif(op == "3"):
update_info()
elif(op == "4"):
check_info()
elif(op == "5"):
save_file()
elif(op == "0"):
exit(0)
main()