导图社区 Python学习
这张思维导图全面且系统地梳理了Python语言学习的主要内容和进程,系统教学,跟着能实操的,断断续续写了一年多,适合Python学习者作为学习路径的参考。
编辑于2025-11-06 10:19:28这是一个关于bat脚本(window命令)的思维导图,bat文件是dos下的批处理文件。批处理文件是无格式的文本文件,它包含一条或多条命令。它的文件扩展名- 为 .bat 或 .cmd。在命令提示下输入批处理文件的名称,或者双击该批处理文件,系统就会调用cmd.exe按照该文件中各个命令出现的顺序来逐个运行它们。
这是一个关于Excel高级函数 VLOOKUP函数使用的思维导图,系统地介绍了Excel中VLOOKUP函数的使用方法,适合用于学习和查阅该函数的相关知识。
这是一个关于Python全部的错误类型的思维导图,列出了Python中的全部错误类型和警告类型,并对每种类型进行了简要说明,有助于理解Python中各种异常和警告的分类及其应用场景,对于调试和错误处理非常有帮助。
社区模板帮助中心,点此进入>>
这是一个关于bat脚本(window命令)的思维导图,bat文件是dos下的批处理文件。批处理文件是无格式的文本文件,它包含一条或多条命令。它的文件扩展名- 为 .bat 或 .cmd。在命令提示下输入批处理文件的名称,或者双击该批处理文件,系统就会调用cmd.exe按照该文件中各个命令出现的顺序来逐个运行它们。
这是一个关于Excel高级函数 VLOOKUP函数使用的思维导图,系统地介绍了Excel中VLOOKUP函数的使用方法,适合用于学习和查阅该函数的相关知识。
这是一个关于Python全部的错误类型的思维导图,列出了Python中的全部错误类型和警告类型,并对每种类型进行了简要说明,有助于理解Python中各种异常和警告的分类及其应用场景,对于调试和错误处理非常有帮助。
Python语言学习总览
第一章 愉快的开始
py启动
1.可通过IDLE启动
注:安装 Python 后,会自动安装一个 IDLE,它是一个 Python Shell (可以在打开的 IDLE 窗口的标题栏上看到),程序开发人员可以利用 Python Shell 与 Python 交互
3.其他py编辑器(如VS code、Pycham、kite、vim)
2.window的cmd窗口(/Linux的黑色命令窗口)
认识Python(以下简称Py)
可通过官网下载安装,苹果系统默认自带2.0版本
语法相对C语言,非常精简,适合办公操作。
版本3.0完全不兼容2.0,需学3.0及以上。
py的简单用途(可上手实操)
可加减乘除运算
>>>print(5+3) 8
>>>print(11*11) 121
可以字词组合打印
>>>print("well water"+"river") well water river
第二章 用Python设计第一个游戏
2.1 一个小游戏
# p _2.py "--- 第一个小游戏---" temp = input ("不妨猜一下小甲鱼现在心里想的是哪个数字:") guess = int (temp) if guess == 8: print("你是小甲鱼心里的蛔虫吗?!") print("哼,猜中了也没有奖励!") else: print("猜错啦,小甲鱼现在心里想的是8!") print("游戏结束,不玩了。^_^")
提示: Tab按键作用: 1.缩进 2.IDLE会提供一些建议。 输入"pr TAB"会显示所有可能的命令供参考。
if "条件" #if条件成立,执行if缩进下的内容 print(~~~) #执行结果 else: #if条件不成立,执行else缩进下的内容 print(~~~) # 执行结果
input() #"展示内容并请输入:",并将输入的内容纳入运算。
2.3 BIF (Built-in Functions 内置函数)
内置函数是为了方便程序员快速编写脚本程序。 例如:
help() 这也是一个BIF #显示BIF的功能描述,例如
>>>help(print) help on built-in function print in module builtines: (帮助打印输出运算结果)
input()也是一个BIF,作用是"接受用户信息并将其返回"
print()是一个BIF,功能是"打印到屏幕"
2.2 缩进
缩进是Python的灵魂。 输入冒号":",切换下一行后会自动缩进。
第三章 成为高手前的基础知识
3.1 变量 variable
定义:给一个值取名字,把它储存在内存当中,这个内存就是称之为变量。又叫给变量赋值,或者把值储存在变量中。
>>>teacher = "小甲鱼" >>>print(teacher) 小甲鱼
赋值:
>>>x = 3 >>>x = 5 >>>y = 8 >>>z = x + y >>>print(z) 13
1.等号"="是赋值,等号左边是名字,右边是值。 2.使用变量前,需要对其先赋值。 3.变量名可以是字母、数字、下划线,但是变量名不可以是数字开头 4.字母可以大小写。但是,大小写的字母是两个不同的名字。 5.对变量的命名可以取任何合法的名字,但请专业一点。
3.2 字符串
字符串就是引号内的一切东西,也称文本。
数字相加,会得到结果: >>>5+8 13 加上引号,会成为字符串的拼接: >>>'5'+'8' 58
引号的使用与矛盾
使用单引号或者双引号没有区别,但一定要成对。 syntax Error:Eol while scanning string literal #语法错误:字符串内错误。
字符串如果需要用到某一种引号,而出现下面的错误: >>>'Let's go' syntax Error: invalid syntax #语法错误:无效语法
解决1:使用转义符号"\": >>>'Let\'s go'
解决2:引用不同引号: >>>"Let's go" Let's go
3.3 原始字符串
定义:在字符串的前面加一个"R",即可定义字符串为原始字符串。
作用: 一个字符串中有多个反斜杠,可能使代码变得混乱,就可以使用原字符串来防止混乱。
案例: >>>string = ′c:\now′ >>>string ′c:\now′ >>>print(string) c: ow
解释: "\"和"n"在一起时构成了"\n",但,"\n"在计算机中是换行符。 所以"c:/now"中"/n"被转义成了换行和消耗了。
改进方法1:使用反斜杠来转义反斜杠: >>>string = 'c:\\now' >>>string 'c:\\now' >>>print(string) c:\now
改进方法2:使用"r"来定义原始字符串,进行打印输出 >>>string =r′c:\now′ >>>string ′c:\\now′ >>>print(string) c:\now
提示:使用字符串时,不论是否为原始字符串,都不能以反斜杠"/"做结尾。
>>>string = "Fish C\" Sytax Error:EOL while scanning string literal #语法错误:字符串内错误
3.4 长字符串
作用:方便打印出来多行的字符串
案例: 打印如下 从明天起,做一个一个幸福的人 喂马,劈柴,周游世界 从明天起,关心粮食和蔬菜 我有一所房子,面朝大海,春暖花开 从明天起,和每一个亲人通信 告诉他们我的幸福 那幸福的闪电告诉我的 我将告诉每一个人 给每一条河,每一座山取一个温暖的名字 陌生人,我也为你祝福 愿你有一个灿烂的前程 愿你有情人终成眷属 愿你在尘世获得幸福 我只愿面朝大海,春暖花开
方法一:使用多个换行符
>>>print("从明天起,做一个一个幸福的人\n喂马,劈柴,周游世界\n从明天起,关心粮食和蔬菜\n我有一所房子,面朝大海,春暖花开\n\n从明天起,和每一个亲人通信\n告诉他们我的幸福\n那幸福的闪电告诉我的\n我将告诉每一个人\n\n给每一条河,每一座山取一个温暖的名字\n陌生人,我也为你祝福\n愿你有一个灿烂的前程\n愿你有情人终成眷属\n愿你在尘世获得幸福\n我只愿面朝大海,春暖花开")
方法二:使用三重引号("""内容"""):
>>>print(""" 从明天起,做一个一个幸福的人 喂马,劈柴,周游世界 从明天起,关心粮食和蔬菜 我有一所房子,面朝大海,春暖花开 从明天起,和每一个亲人通信 告诉他们我的幸福 那幸福的闪电告诉我的 我将告诉每一个人 给每一条河,每一座山取一个温暖的名字 陌生人,我也为你祝福 愿你有一个灿烂的前程 愿你有情人终成眷属 愿你在尘世获得幸福 我只愿面朝大海,春暖花开 """)
提示:除了字符串内所有符号都使用英文! 英文:"" () 中文:“” ()
3.5 改进我们的小游戏
分析问题: 1、当用户猜错时给提示,例如,大了还是小了? 2、每次运行一次程序只能猜一次,应该提供多次机会,至少三次。 3、答案应该是随机的,因为程序固定,容易导答案外泄。
3.6 条件分支
计算机的值的比较, 在Python中的比较操作符有: <小于 <= 小于等于 >大于 >= 大于等于 == 等于 #一个等于号"="是赋值 != 不等于
如,在IDLE中进行1和3的比较: >>>1 < 3 True >>>1 > 3 False >>>1 == 3 False >>>1 != 3 True
提示:在比较符号两边都留了一个空格,这是非必需的,只是为了美观。
3.7 初识循环
while循环语法
#p3_1.py temp = input("不妨猜一下小甲鱼现在想的是哪个数字:") guess = int(temp) #把int(temp)(用户输入值) 赋予guess (检验值) while guess != 8: #当检验值不等于8开始循环以下内容,否则跳过此次循环。 if guess > 8: print("哥,大了大了~~~") else: print("嘿,小了小了~~~") temp = input("请再试试吧:") guess = int(temp) print("哎呀,你是小甲鱼心里的蛔虫吗?!")
3.8 引入外援 random模块
定义:生成随机数相关模块。
IDLE使用:
>>>import random >>>random.randint(1,10) 2 >>>random.randint(1,10) 5 >>>random.randint(1,10) 6
改进:
# p3_2.py import random Secret = random.randint(1,10) #把random随机值(范围为1~10的一个整数值) 赋予 secret(最终值) temp = input("不妨猜一下小甲鱼现在心里想的是哪个数字:") guess = int(temp) times = 1 #time(循环值)为1 while (guess != Secret) and (times < 3): if guess > Secret: print("哥,大了大了~~~") else: print("嘿,小了小了~~~") temp = input("请再试试吧:") guess = int (temp) times = times + 1 if (times <=3) and (guess == Secret): print("哎呀,你是小甲鱼心里的蛔虫吗了?!") print("哼,猜中了也,没有奖励噢~") else: print ("唔,给三次机会都猜错,不跟你玩了!")
步骤解析: 第一步,先从random模块中取一个1~10内的随机整数赋给secret; 第二步,设置用户输入模块inpu并且设置输入用语"不妨猜一下小甲鱼现在...",同时把值赋给temp; 第三步,把用户输入值temp规范成数值,并赋给guess; 第四步,设置循环次数模块time,同时每次运行完,循环值加1; 第五步,设置循环模块while,只要同时符合条件:guess 不等于 secret 和 循环次数小于3 就进入循环: 加入if/else模块: guess 大于 secret,就打印输出 "哥,大了大了~", 否则(guess小于secret 成立),打印输出"嘿,小..." 接下来,设置用户输入input模块并设置输入用语"请再试试吧",同时赋值给temp 然后,把用户输入值temp规范成数值,并赋给guess 还有,循环值加1 循环完成第一次,开始重新判断条件准备执行下一次循环。 第六步,加入if/else模块:只要同时满足循环次数小于3和 guess 等于 secret,就打印输出"哎呀,你是小甲鱼心里的...“和"哼,猜中了也没有奖励噢~";否则打印输入"唔,三次机会都猜错..."
3.9 闲聊 变量类型
定义:Python的变量是没有类型的,它的变量更像是名字的标签,想贴就贴哪了(/可以随便赋值)。这里指的是使用变量时,不管什么变量类型都正常使用。
3.9.1 整数型
就是常见的整数,在Python3中整数与长整数无缝结合了。使用整数运算,没有长度的限制,只限于计算机的虚拟内存总数。
3.9.2 浮点型
浮点型就是平时的小数。
Python区分整数和浮点型的唯一方式就是看有没有小数点。
E记法 平时说的科学计数法。 用于记录特别大和特别小的数。例如:
>>>a = 0.0000000000000000000025 #小数点后有22位数 >>> a 2.5e-21
地球到太阳的距离是1.5×10的8次方千米。 e记法: 1.5e11 (单位:米)
3.9.3布尔类型 bool()
只有 true 和 false 两种情况
3.9.4 类型转化
int()
将一个字符串或浮点数转换为一个整数。 例子如下:
>>>a = ′520′ >>>b = int (a) >>> a,b (′520′,520) >>>c = 5.99 >>>d = int (c) >>> c,d (5.99,5)
float()
将一个字符串或者整数转换成浮点数(小数)。 举例,如下:
>>>a =′ 520′ >>>b = float (a) >>>a,b (′520′,520.0) >>>c = 520 >>>d =float (c) >>>c,d (520,520.0)
str()
将一个数或其他任何类型转换成一个字符串。 举例,如下:
>>> a = 5.99 >>> b = str (a) >> b ‘5.99' c = str(5e15) >>> c '500000000000000.0'
3.9.5 检验 值的类型 的 函数
1.type()函数:
>>> type (′520′) <class ′str′> >>> type (5.20) <class ′float′> >>>type (5e20) <class ′float> >>>type (520) <class ′str′> >>>type(True) <class ′bool′>
2.isinstance()函数:
有两个参数; 一个是待确定类型的数据;第二个是指定一个数据类型; 这个更适合用来判断变量类型。 举例:
>>> a = "小甲鱼" >>>isinstance (a,str) True >>>isinstance (520,float) False >>>isinstance (520,int) True
3.10 常用操作符
1).算术运算符: + - * / % ** // 加 减 乘 除 求余数 幂运算 floor除法
1.由于在Python中"="是变量赋值,所以在表达 a=a+1,b=b-3 这类操作符特别麻烦。所以做了一些简化:
>>>a = 10 >>>a += 1 #相当于 a=a+1 >>>print(a) 11 >>>b = c = d = 10 >>>b -= 3 #相当于 b=b-3 >>>c *= 10 #相当于 c=c*10 >>>d /= 8 #相当于d=d÷8 >>>print(b,c,d) 7 100 1.25
2.floor除法(地板除法) 该算法是将除法计算的结果舍弃小数,取整数。 在多数编程语言中一般采用floor除法。 在Python3中取用的是真正的除法,想要使用地板除法,就只有使用该除号"//"
3.幂运算(**) 举例:
>>>5 ** 2 #5的二次幂(二次方) 25 >>>5 ** -2 #5的负二次幂(1/25) 0.04
2).优先级问题
和数学中的运算顺序一样:先乘除后加减,如果有括号先运算括号里面的。
3).比较操作符 < <= > >= == != 小于 小于等于 大于 大于等于 等于 不等于
>>>3 < 4 True >>>1 + 1 >= 2 True >>>′a′ >′b′ False >>>5/2 <= 3 True >>>5 > 3 < 4 True
4).操作逻辑符 and or not and:只有两边同时满足的条件才为“True”,否则为“False”。 or:满足任意一边的条件就可以为 True ,否则为 False。 not:一元操作符,作用是得到一个和操作数相反的布尔类型的值。 总之,根据表达式的值的真假,返回布尔型值,例如:
>>> 3 > 4 and 4 < 5 False >>>3 < 4 and 4 < 5 True
>>> not true false >>>not 0 true >>> not 4 false
特别提示: 1. Not操作符会把对象转化成True/False,然后逆反。 2.如果是int/float型,0就是False,其他是True 3.布尔型:True 相当于 1,False 相当于 0
第四章 了不起的分支和循环
4.1 分支和循环
作者开头引语 “机器马生汇编汇编C,语言C,语言生万物。” 编程语言没有最厉害的,只有最合适的。面对不同的环境和需求,就会有不同的编程工具去迎合。 分支和循环在套用一个打飞机的小游戏来体现就是: 开始游戏进入一个大循环,在没有触发死亡机制之前,循环不止。 框架如下: 加载bgm 播放bgm 我方飞机诞生 while True: if 用户是否登记了关闭按钮: 退出程序 if 每隔一段时间: 产生一定数量的敌方飞机 敌方飞机移动 屏幕刷新 if 用户鼠标事件 我方飞机位置=鼠标用户位置 屏幕刷新 if 我方飞机被敌方飞机撞击: 我方飞机扑街,播放撞击音效 打印 游戏结束 停止bgm
4.2 快速上手 分支的含义:只有符合条件才会去做某一件事情; 循环的含义:只要符合条件就会持续做某一件事情。 练习: 成绩按照分数划分等级90分以上为a,80~90为B,60~80为C,60以下为D。现在要求写一个程序,当用户输入分数时会自动转换A、B、C或D。
解答如下:
temp = input("请输入你要查询的分数:") number = int(temp) if 100 >= number >= 90: print("等级为A") if 90 > number >= 80: print("等级为B") if 80 > number >= 60: print("等级为C") if 60 > number >= 0: print("等级为D") if number > 100 and number < 0: print("输入错误!请输入0~100的整数。")
或者:
number = input("请输入你要查询的分数:") if 100 >= number >= 90: print("等级为A") else: if 90 > number >= 80: print("等级为B") else: if 80 > number >= 60: print("等级为C") else: if 60 > number >= 0: print("等级为D") else: print("输入错误,请输入0~100的整数!")
或者,还可以简写:
#p4_3.py score = int (intput ('请输入一个分数‘)) if 100 >= score >= 90: print (‘A‘) elif 90 > score >= 90: print (‘B‘) elif 80 > score >= 60: print ('C‘) elif 60 > score >= 0: print (‘D‘) else: print("输入错误!”)
4.3 避免“悬挂else”问题
悬挂:当出现两个if,一个else的时候。计算机可能会判断失误,正常该执行else,却不执行else的结果反而去执行第二个if的结果。悬挂在c语言中比较常见,老司机也可能中招。 参考如下:
//p4_4.c #这是C语言代码
4.4 条件表达式(三元操作符)
简介:通常n操作符是指该操作符有n个操作数。
如赋值操作符“=“,它是一个二元操作符。“-“这是一个一元和二元操作符,作为负号时是一个一元操作符,作为减号时,是一个二元操作符。
三元操作符:
例子:
if x < y: small = x else: small = y
改进:
small = x if x < y else y
三元操作符,会复杂化程序结构:
正常: #p4_6.py score = int (intput ('请输入一个分数‘)) if 100 >= score >= 90: print (‘A‘) elif 90 > score >= 90: print (‘B‘) elif 80 > score >= 60: print ('C‘) elif 60 > score >= 0: print (‘D‘) else: print("输入错误!”)
三元操作符形式: p4_7.py score = int(input('请输入一个分数:')) level = 'A' if 100 >= score >= 90 else 'B' if 90 > score >= 80 else 'C' if 80 > score >= 60 else 'D‘ if 60 > score >=0 else print ('输入错误!) print(level)
4.5 assert 断言
简介:翻译为“断言”,是一个判断式。 用法: assert 后接 [条件],当条件为假时,程序崩溃并抛出 AssertionError 异常。用作程序测试时尽可能发现更多的bug:
>>> assert 3 < 4 #上述判断回车后,没有任何异常,所以可以接着输入下一条判断。 >>> assert 3 > 4 Traceback (most recent call last) : File "<pyshell#100>",line 1, in <module> assert 3 > 4 AssertionError
4.6 while 循环语句
简介:while是一个循环,只要条件为真,就一直循环。 语法如下:
while + 条件: 循环体
下面代码将打印1+2+3+……+100的计算结果:
#P4_8.py i = 1 sum = 0 while i <= 100: sum += 1 i += 1
提示:设计循环体的时候,要考虑退出的循环条件 [i=i+1]。否则循环不会结束,也称死循环。 在某些程序设计当中,死循环又是必不可少的特性。例如服务器,负责网站收发的程序,再如游戏开发。
4.7 for 循环语句
语法: for 变量 in 可迭代对象: 循环体
可迭代对象就是指那些元素可以被单独提取出来的对象。如目前最熟悉的字符串。像“Fishc"正是由[f i s h c] 五个字符元素构成。那么for循环的语句每一次执行就会从该字符中。拿出一个字符,然后存放到变量中。
例子:想要通过for语句来实现1+2+3+...+100 的计算结果:
错误的写法: #p4_9.1.py sum = 0 for i = 100: sum += i print (sum)
100 是一个整数,不是“可迭代对象”
正确写法: sum = 0 for i in range (101): sum = sum + i print (sum)
BIF函数,可以为指定的整数生成一个数字序列(可迭代对象)语法如下: range (stop) range (strat, stop) range (strat, stop, step)
辅助函数: range () 函数
>>> range (10) range(0, 10) >>> range (1,10) range(1, 10) >>> range (1,10,2) range(1, 10, 2) >>>
辅助函数:list 函数
list 是将可迭代对象以列表的方式展示出来。
>>> range (1,10) range(1, 10) >>> list (range (1,10)) [1, 2, 3, 4, 5, 6, 7, 8, 9]
4.8 break 语句 跳出循环
语法:if + 条件 : break
简介:如果 条件成立,则跳出循环。举如下:
# p4_11.py bingo = "清蒸" answer = input ('小甲鱼是清蒸还是红烧好吃?\n') while True: if answer == bingo: break answer = input ("很抱歉,答案错误,请重新输入\n") print ("对嘛,只有清蒸才能原汁原味~")
4.9.continue 语句
简介:作用是跳出本轮循环,并开始下一轮循环。(在进行下一轮循环之前,会先测试循环条件。)
p4_13.py for year in range(2018,2050): if (year % 4 == 0) and (year % 100 != 0) or (year % 400 == 0): print (year) continue
else 语句
else 不仅可以接在if的后面,还可以接在while和for循环语句的后面,表示当条件不成立的时候执行。在正常情况下,写不写else都是一样的,除了下面这种:
p4_12.py for year in range(2018,2100): if (year % 4 == 0) and (year % 100 != 0) or (year % 400 == 0): break print ("2018年以后出现的第一个闰年是",year)
p4_15.py for year in range(2018,2100): if (year % 4 == 0) and (year % 100 != 0) or (year % 400 == 0): break else: print ("2018年以后出现的第一个闰年是",year)
区别
在p4_15.py 的程序中,break语句使得程序跳出循环,但不会执行else中的内容。
第五章 列表、元祖和字符串
5.1 列表
5.2 元组 tuple
含义:元组和列表最大的区别是元组,只可以读,不可以写。
元组用小括号 (),也可以省略小括号。
>>> rhyme = (1,2,3,4,5,"上山打老虎") >>> rhyme ( 1,2,3,4,5,‘上山打老虎′) >>> rhyme = 1,2,3, 4, 5,“上山打老虎" >>> rhyme ( 1,2,3,4,5, ′上山打老虎′)
5.2.1 创建与访问
>>> rhyme = (1,2,3,4,5,"上山打老虎") >>> rhyme ( 1,2,3,4,5,‘上山打老虎′) >>> rhyme = 1,2,3, 4, 5,“上山打老虎" >>> rhyme ( 1,2,3,4,5, ′上山打老虎′)
5.2.1.2 更新和删除元组
首先由于元组无法修改,那么要修改元组本身就是一件麻烦的事情。
>>> x_man = ("金刚狼","X教授","暴风女","火凤凰","镭射眼") >>> x_man [1] = '小甲鱼' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'tuple' object does not support item assignment
所以需要使用到切片,和拼接实现更新元组
>>> x_man = (x_man[0],'小甲鱼') + x_man[2:] >>> x_man ('金刚狼', '小甲鱼', '暴风女', '火凤凰', '镭射眼')
使用 id()函数 可检验元组是否修改
>>> x_man = ("金刚狼","X教授","暴风女","火凤凰","镭射眼") >>> id (x_man) 2191063416560 >>> x_man = (x_man[0],'小甲鱼') + x_man[2:] >>> id (x_man) 2191063764240
删除元素 使用技巧同上
>>> x_man = ("金刚狼","X教授","暴风女","火凤凰","镭射眼") >>> x_man = x_man[:1] + x_man[2:] >>> x_man ('金刚狼', '暴风女', '火凤凰', '镭射眼')
5.3 字符串
1.含义:在一些编程语言中字符和字符串是两个不同的概念。分别使用单、双引号区分。但,Python中不区分。 字符串和元组一样都是不可以修改的,只能通过切片技巧来拼接。
2.内置方法总结1:
案例1:
>>> str1 'FISHC' >>> str1.casefold ( ) 'fishc' >>> str1 'FISHC'
capitalize()
将字符串的第一个字符修改为大写,其他字符全部改为小写
casefold()
将字符串的所有字符修改为小写
center(width[,fillchar])
当字符个数大于width时,字符串不变; 当字符个数小于 width时,字符串居中,并在左右填充空格 以达到width 指定宽度; fillchar参数可选,指定填充的字符(默认是空格)
count(sub[,start[,end]])
返回sub参数在字符串里边出现的次数; start和end参数可选,指定统计范围
encode(encoding='utf-8',errors='strict')
以encoding 参数指定的编码格式对字符串进行编码,并返回errors参数指定出错时的处理方式,默认是抛出 UnicodeError异常,还可以使用'ignore'、'replace'、'xmlcharrefreplace'、'backslashreplace'等处理方式
endswith(sub[,start[,end]])
检查字符串是否以sub参数结束,如果是返回True,否则返回False;start和end参数可选,指定范围
expandtabs(tabsize=8)
把字符串中的制表符(\t)转换为空格代替
find(sub[,start[,end]])
检查sub参数是否包含在字符串中,如果有则返回第一个出现位置的索引值,否则返回-1;start和end参数可选,表示范围
index(sub,[start],[end])
跟 find()方法一样,不过该方法如果找不到将抛出一个ValueError 异常
isalnum()
如果字符串仅由字母或数字构成则返回True,否则返回False
isalpha()
如果字符串仅由字母构成则返回True,否则返回False
isdecimal()
如果字符串仅由十进制数字构成则返回True,否则返回False
isdigit()
如果字符串仅由数字构成则返回True,否则返回False
islower()
如果字符串仅由小写字母构成则返回True,否则返回False
isnumeric()
如果字符串仅由数值构成则返回True,否则返回False
isspace()
如果字符串仅由空白字符构成则返回True,否则返回False
istitle()
如果是标题化(所有的单词均以大写字母开始,其余字母皆小写)字符串则返回True,否则返回False
5.3.2 格式化
1.format() 传递
>>> "{0} love {1}.{2}".format("I", "FishC", "com") ′I love FishC.com′
位置参数:1,2,3
>>> "{a} love {b}.{c}".format(a="I", b="FishC", c="com") 'I love FishC.com'
关键字参数:a,b,c
>>> "{0}:{1:.2f}".format("圆周率", 3.14159) ′圆周率:3.14′
“.2”的意思是四舍五入到保留两位小数点,而f的意思是浮点数
2.格式化操作符:%
% 当它出现在字符中的时候,它表示的是格式化操作符
>>> ′%c′ % 97 ′a′ >>> ′%c%c%c%c%c′ % a ′FishC′ >>> ′%d转换为八进制是:%o′ % (123, 123)
5.4 序列
定义: · 都可以通过索引得到每一个元素。 · 默认索引值总是从0开始(当然灵活的Python还支持负数索引)。 · 可以通过切片的方法得到一个范围内的元素的集合。 · 有很多共同的操作符(重复操作符、拼接操作符、成员关系操作符)。
1.list
定义:list()方法用于把一个可迭代对象转换为列表
举例:
>>> # 创建一个空列表 >>> a = list() >>> a [] >>> # 将字符串的每个字符迭代存放到列表中 >>> b = list("FishC") >>> b [′F′, ′i′, ′s′, ′h′, ′C′] >>> # 将元组中的每个元素迭代存放到列表中 >>> c = list((1, 1, 2, 3, 5, 8, 13)) >>> c [1, 1, 2, 3, 5, 8, 13]
2. tuple([iterable])
tuple()方法用于把一个可迭代对象转换为元组,具体的用法和list()一样
3. str(obj)
str()方法用于把obj对象转换为字符串,这个方法3.9.4节中讲过
4. len(sub)
该方法用于返回sub参数的长度:
>>> str1 = "I love fishc.com" >>> len(str1) 16 >>> list1 = [1, 1, 2, 3, 5, 8, 13] >>> len(list1) 7 >>> tuple1 = "这", "是", "一", "个", "元祖" >>> len(tuple1) 5
5. max()
max()方法用于返回序列或者参数集合中的最大值
>>> list1 = [1, 18, 13, 0, -98, 34, 54, 76, 32] >>> max(list1) 76 >>> str1 = "I love fishc.com" >>> max(str1) ′v′ >>> max(5, 8, 1, 13, 5, 29, 10, 7) 29
#猜想下 max (tuple1)的实现方式 temp =tuple1[0] for each in tuple1 : if each > temp : temp = each return temp
for each in tuple1: #从元组1从逐个取出元素进行操作:
6. min()
min()方法跟max()用法一样,但效果相反:返回序列或者参数集合中的最小值。
7. sum(iterable[, start])
用于返回序列iterable的所有元素值的总和 sum()方法有一个可选参数(start),如果设置该参数,表示从该值开始加起,默认值是0
>>> tuple1 = 1, 2, 3, 4, 5 >>> sum(tuple1) 15 >>> sum(tuple1, 10) 25
8. sorted(iterable, key=None, reverse=False)
(对象,按什么排序,是否反序)
sorted()方法用于返回一个排序的列表 列表的内建方法sort()是实现列表原地排序
>>>list1=[1,18,13,0,-98,34,54,76,32] >>>list2=list1[:] >>>list1.sort() >>>list1 [-98,0,1,13,18,32,34,54,76] >>> sorted (list2) [-98,0,1,13,18,32,34,54,76] >>>list2 [1,18,13,0,-98,34,54,76,32]
9.reversed(sequence)
reversed()方法用于返回逆向迭代序列的在经过reversed()的作用之后, 返回的是一个把序列值经过反转之后的迭代器,所以需要通过遍历,或者List或者next()等方法获取作用后的值。 原来序列不会改变。
#将列表进行逆序 print([x for x in reversed([1,2,3,4,5])]) #将元组进行逆序 print([x for x in reversed((1,2,3,4,5))]) #将字符串进行逆序 print([x for x in reversed("abcdefg")]) #将 range() 生成的区间列表进行逆序 print([x for x in reversed(range(10))])
[5, 4, 3, 2, 1] [5, 4, 3, 2, 1] [′g′, ′f′, ′e′, ′d′, ′c′, ′b′, ′a′] [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
#将列表进行逆序 print(list(reversed([1,2,3,4,5])))
>>>list1=[1,18,13,0,-98,34,54,76,32] >>> reversed (list1) < list _ reverseiterator object at 0x000000000324F518>>>> for each in reversed (list1): print ( each , end =',') 32,76,54,34,-98,0,13,18, l #AI识图,实例仅供参考。
10. enumerate(iterable)
生成由二元组(二元组就是元素数量为2的元组)构成的一个迭代对象, 每个二元组由可迭代参数的索引号及其对应的元素组成
>>>str1=" FishC " >>> for each in enumerate (str1): print (each) (0,′F′) (1,′i′) (2,′s′) (3,′h′) (4,′C′)#AI识图,实例仅供参考。
11. zip(iter1 [,iter2 [...]])
zip()方法用于返回由各个可迭代参数共同组成的元组,举个例子:
>>> list1 =[1,3,5,7,9] >>>str1=" FishC ” >>> for each in zip (list1,str1): print ( each ) (1,′F′) (3,′i′) (5,′s′) (7,′h′) (9,′C′) >>>tuple1=(2,4,6,8,10) >>> for each in zip (1ist1,str1, tuplel ): print ( each ) (1,′ F ′,2) (3,′ i ′,4) (5,' s ′,6) (7,′ h ',8) (9,′ C ',10)#AI识图,实例仅供参考。
第六章 函数
6.1 Python的乐高积木
6.1.1 创建和调用函数
Python中创建一个函数用def关键字:
>>> def myFirstFunction (): print ("这是我创建的第一个函数!"") print ("我表示很激动……”) print ("在这里,我要感谢 TVB ,感谢 CCTV !"") #图转
调用一个函数,直接写出函数名加上小括号即可:
>>> myFirstFunction() 这是我创建的第一个函数! 我表示很激动…
假如想把刚才的内容打印3次,只需要调用3次函数即可:
>>>for i in range (3): myFirstFunction ()
6.1.2 函数的参数
参数就是使得函数可以实现个性化
>>>def mySecondFunction ( name ): print ( name +"是帅锅!") >>> mySecondFunction ("小甲鱼") 小甲鱼是帅锅! >>> mySecondFunction ("小鱿鱼") 小鱿鱼是帅锅! >>> mySecondFunction ("小丑鱼") 小丑鱼是帅锅!
使用多个参数,只需要使用逗号隔开即可:
>>> def add (num1,num2): print (num1+num2) >>> add (1,2) 3
6.1.3 函数的返回值
函数返回一些数据来报告执行的结果
>>> def fire (): pass #此处添加炮弹的发射细节 return "轰,发射成功!" >>> fire () '轰,发射成功!′ >>> def add (num1,num2): return num1+num2 >>> add (1,2) 3 >>> def div ( numl ,num2): if num2==0: return "除数不能为 0 ” else : return num1/num2 >>> div (3,0) '除数不能为0 >>> div (3,5) 0.6 #图转
在Python中,并不需要定义函数的返回值类型,函数可以返回不同类型的值;而如果没有返回值,则默认返回None。
>>> def hello (): print (" Hello ~") >>> print ( hello ()) Hello ~ None
如果返回了多个值,Python默认是以元组的形式进行打包
>>> def test (): return 1,'小甲鱼',3.14 >>> test () (1,'小甲鱼',3.14)
当然,也可以利用列表将多种类型的值打包到一块儿再返回
>>> def test (): return [1,"小甲鱼',3.14] >>> test () [1,'小甲鱼',3.14]
6.2 灵活即强大
6.2.1 形参和实参
形参指的是函数定义的过程中小括号里的参数, 实参则指的是函数在被调用的过程中传递进来的参数
举个例子:
>>> def sayHi ( name ): print ("嗨,% s " % name ) >>> sayHi ("小甲鱼") 嗨,小甲鱼
sayHi(name)中的name是一个形参,因为它只是代表一个位置、一个变量名
sayHi("小甲鱼")传递的"小甲鱼"则是一个实参,因为它是一个具体的内容,是赋值到变量name中的值
6.2.2 函数文档
描述该函数的功能以及一些注意事项: 这个字符串称为函数文档,它的功能与代码注释是一样的。
>>> def exchangeRate ( dollar ): """ 功能:汇率转换,美元->人民币 汇率:6.54 日期:2018-06-25 """ return dollar *6.54 >>> exchangeRate (10) 65.4
函数的文档字符串可以通过特殊属性_ _doc_ _获取
>>> print ( exchangeRate .__ doc __) 功能:汇率转换,美元﹣>人民币 汇率:6.54 日期:2018-06-25
当想使用一个BIF却又不确定其用法的时候,可以通过help()函数来查看函数的文档:
>>> help ( exchangeRate ) Help on function exchangeRate in module __main __: exchangeRate ( dollar ) 功能:汇率转换,美元->人民币 汇率:6.54 日期:2018-06-25
6.2.3 关键字参数
关键字参数其实就是在传入实参时明确指定形参的变量名
>>> def eat ( somebody , something ): print ( somebody +'把+ something +′吃了′) >>> eat ("小甲鱼","蛋糕”) 小甲鱼把蛋糕吃了 >>> eat (“蛋糕","小甲鱼") 蛋糕把小甲鱼吃了 >>> eat ( something ="蛋糕", somebody ="小甲鱼") 小甲鱼把蛋糕吃了
在调用函数的时候,位置参数必须在关键字参数的前面,否则就会出错:
位置固定的参数称为位置参数:第一是somebody,第二是something,这就是位置参数。
6.2.4 默认参数
Python的函数允许为参数指定默认的值,那么在函数调用的时候如果没有传递实参,则采用默认参数值:
>>> def saySomething ( name ="小甲鱼", word ="让编程改变世界!"): print ( name +′->′+ word ) >>> saySomething () 小甲鱼->让编程改变世界! >>> saySomething ("苏轼","不识庐山真面目,只缘身在此山中。") 苏轼->不识庐山真面目,只缘身在此山中。 >>> saySomething ( word ="古之成大事者,不惟有超世之才,亦有坚忍不拔之志。", name ="苏轼") 苏轼->古之成大事者,不惟有超世之才,亦有坚忍不拔之志。
结合默认参数和关键字参数,可以使函数的调用变得非常灵活:
>>> def watchMovie ( name ="小甲鱼", cigarette = True , beer = True , girlfriend = True ): sentence = name +"带着" if cigarette : sentence = sentence +"香烟" if beer : sentence = sentence +"啤酒" if girlfriend : if cigarette or beer : sentence = sentence +"和女朋友" else : sentence = sentence +"女朋友" sentence = sentence +"去看电影!" return sentence >>> watchMovie () '小甲鱼带着香烟啤酒和女朋友去看电影! >>> watchMovie ( name ="不二", girlfriend = False ) 不二带着香烟啤酒去看电影!
6.2.5 收集参数
这个名字看起来比较新鲜,其实大多数时候它也被称为可变参数。有时候,可能函数也不知道调用者实际上会传入多少个实参.例如我们熟悉的print()函数就是这样:
>>> print(1, 2, 3, 4, 5) 1 2 3 4 5 >>> print("I", "Love", "FishC") I Love FishC
若实参个数不确定,在定义函数的时候,形参就可以使用收集参数来“搞定”。而语法也很简单,仅需要在参数前面加上星号(*)即可:
>>> def test (* params ): print ("有 %d 个参数"% len ( params )) print ("第一个参数是:", params [1]) >>> test (′ F ′,′ i ′,′ s ′,′ h ',' C ′) 有5个参数 第二个参数是: i >>> test ("小甲鱼",123,3.14) 有3个参数 第二个参数是:123
Python就是把标志为收集参数的参数们打包成一个元组。
>>> def test (* params ): print ( type ( params )) >>> test (1,2,3,4,5) < class ' tuple ′>
如果在收集参数后面还需要指定其他参数,那么在调用函数的时候就应该使用关键参数来指定,否则Python就都会把实参都纳入到收集参数:
>>> def test (* params , extra ): print ("收集参数是:", params ) print ("位置参数是:", extra ) >>> test (1,2,3,4,5) Traceback ( most recent cal1 last ): File "<pyshel1#12>", line 1, in < module > test (1,2,3,4,5) TypeError : test () missing 1required keyword - only argument :' extra ' >>> test (1,2,3,4, extra =5) 收集参数是:(1,2,3,4) 位置参数是:5
如果定义的函数中带有收集参数,那么可以将其他参数设置为默认参数,例如,print()的原型如下:
print(*objects, sep=′ ′, end=′\n′, file=sys.stdout, flush=False)
objects参数是一个收集参数,如果传入多个参数,将依次打印出来; sep参数指定多个参数之间的分隔符,默认是空格; end参数指定以什么字符结束打印,默认是换行符; file参数指定输出的位置;flush指定是否强制刷新缓存。
在函数的定义中,收集参数前面的星号(*)起到的作用称为“打包”操作,通俗的理解就是将多个参数打包成一个元组的形式进行存储。而在实参中的作用则相反,起到“解包”的作用。
>>> num = (1, 2, 3, 4, 5) >>> print(num) (1, 2, 3, 4, 5) >>> print(*num) 1 2 3 4 5
>>> name = "FishC" >>> print(*name) F i s h C >>> list1 = [1, 1, 2, 3, 5] >>> print(*list1) 1 1 2 3 5
6.3 我的地盘听我的
6.3.1 局部变量
#p6_1.py def discount ( price , rate ): final _ price = price * rate return final _ price old _ price = float ( input ('请输入原价:′)) rate = float ( input ('请输入折扣率:")) new _ price = discount ( old _ price , rate ) print ('打折后价格是:%.2f'% new _ price )
其中 final_price 只属于discount函数,不可外部访问。
程序执行效果如下:
>>> 请输入原价:80 请输入折扣率:0.75 打折后价格是:60.00
#p6_2.py def discount ( price , rate ): final _ price = price * rate return final _ price old _ price = float ( input ('请输入原价:')) rate = float ( input ('请输入折扣率:')) new _ price = discount ( old _ price , rate ) print (打折后价格是:%.2f'% new price ) print ('试图在函数外部访问局部变量 final price 的值:号.2f'号 final price )
请输入原价:80 请输入折扣率:0.75 打折后价格是:60.00 Traceback ( most recent cal1 last ): File " C :\ Users \ goodb \ Desktop \p6_2.py", line 11, in < module > print ('试图在函数外部访问局部变量 final price 的值:%.2f'% final _ price) NameErrOr : name ' finalpriceis notdefined
6.3.2 全局变量
与局部变量相对的是全局变量
#p6_1.py def discount ( price , rate ): final _ price = price * rate return final _ price old _ price = float ( input ('请输入原价:′)) rate = float ( input ('请输入折扣率:")) new _ price = discount ( old _ price , rate ) print ('打折后价格是:%.2f'% new _ price )
old_price、new_price、rate都是在函数外面定义的,它们都是全局变量
程序执行效果如下:
>>> 请输入原价:80 请输入折扣率:0.75 打折后价格是:60.00
修改全局变量
1.会导致莫名其妙的bug:
def discount ( price , rate ): final _ price = price * rate #下面试图修改全局变量的值 old _ price =50 print (′在局部变量中修改后 old price 的值是:%.2f'%old _ price ) return final _ price old _ price = float ( input ('请输入原价:′)) rate = float ( input ('请输入折扣率:')) new _ price = discount ( old _ price , rate ) print (全局变量 old _ price 现在的值是:%.2f'%old _ price )
程序执行效果如下:
>>> 请输入原价:80 请输入折扣率:0.75 在局部变量中修改后old_price的值是:50.00 全局变量old_price现在的值是:80.00 打折后价格是:60.00
分析:如果在函数内部试图修改全局变量的值,那么Python会创建一个新的局部变量替代 (名字与全局变量相同),但真正的全局变量是“不为所动”的,所以才有了上面的实现结果。
6.3.3 global关键字
6.3.4 内嵌函数
Python的函数定义是支持嵌套的,也就是允许在函数内部定义另一个函数,这种函数称为内嵌函数或者内部函数。
举个例子:
>>> def fun1 (): print ("fun1()正在被调用…") def fun2(): print ("fun2(正在被调用…") fun2() >>>fun1() fun1(正在被调用… fun2(正在被调用…
提示:内部函数fun2整个作用域都在外部函数fun1之内,不可在fun1的外部调用
6.3.5 LEGB原则
LEGB含义解释: · L-Local:函数内的名字空间。 · E-Enclosing function locals:嵌套函数中外部函数的名字空间。 · G-Global:函数定义所在模块的名字空间。 · B-Builtin:Python内置模块的名字空间。 那么变量的查找顺序依次就是L→E→G→B。
实例:
520 >>> def fun1(): X =88 def fun2(): x = 11 print ( x ) fun2() >>> funl () 11
6.3.6 闭包
如果在一个内部函数里,对在外部作用域但不是在全局作用域的变量进行引用(简言之:就是在嵌套函数的环境下,内部函数引用了外部函数的局部变量),那么内部函数就被认为是闭包。
>>>funX ( x ): def funY ( y ): return X *y return funY >>>temp= funX (8) >>>temp (5) 40
在内部函数中,只能对外部函数的局部变量进行访问,但不能进行修改
>>> def funX (): x =5 def funY (): x = x +1 return x return funY >>> temp = funX () >>> temp () Traceback ( most recent cal1 last ): File "< pyshell #56>", line 1, in < module > temp () File "<pyshel1#54>", line 4, in funY X = x +1 UnboundLoca1Error:local variable ' x ' referenced before assignment
这个错误提示与之前讲解全局变量的时候基本一样,Python认为在内部函数的x是局部变量的时候,外部函数的x就被屏蔽了起来,所以执行x = x + 1的时候,在等号右边根本就找不到局部变量x的值,因此报错。
解决方案:
Python 3以前
并没有直接的解决方案,只能间接地通过容器类型来存放。之前介绍的字符串、列表、元组,这些可以存放各种类型数据的“仓库”就是容器类型。
x =[5] def funY (): x [0]= x [0]+1 return x [0] return funY >>> temp = funX () >>> temp () 6
Python 3
以使用nonlocal关键字告诉Python这不是一个局部变量
x =[5] def funY (): nonlocal x x = x + 1 return x return funY >>> temp = funX () >>> temp () 6
6.3.7 装饰器
将被装饰的函数当作参数传递给与装饰器对应的函数(名称相同的函数),并返回包装后的被装饰的函数。
实例
>>> def eat (): print ("开始吃了")
需要在执行该函数时加上日志:
方法1:
>>> print("开始调用eat()函数…") 开始调用eat()函数… >>> eat() 开始吃了 >>> print("结束调用eat()函数…") 结束调用eat()函数…
者直接将代码封装到函数中:
>>> def eat (): print ("开始调用 eat ()函数...") print ("开始吃了") print ("结束调用 eat ()函数...")
会使得原有的业务逻辑变复杂,这样的代码也不符合“一个函数只做一件事情”的原则
使用装饰器:
使用闭包:
>>> def log ( func ): def wrapper (): print ("开始调用 eat ()函数…") func () print ("结束调用 eat ()函数…") return Wrapper >>> def eat (): print ("开始吃了") >>> eat = log ( eat ) >>> eat () 开始调用 eat ()函数… 开始吃了 结束调用 eat ()函数…
log(eat)将eat函数作为参数传递给log(),由于wrapper()是log()的闭包,所以它可以访问log()的局部变量func,也就是刚刚传递进来的eat,因此,执行func()与执行eat()是一个效果
语法糖(Syntactic sugar),就是在计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。语法糖让程序更加简洁,有更高的可读性。
def log ( func ): def wrapper (): print ("开始调用 eat ()函数...") func () print "结束调用 eat ()函数..") return wrapper @log def eat (): print ("开始吃了") >>> eat () 开始调用 eat ()函数... 开始吃了 结束调用 eat ()函数...
6.4 函数式编程
6.4.1 lambda 表达式
定义:函数式编程是一种古老的编程模式,就是用函数(计算)来表示程序,用函数的组合来表达程序组合的思维方式
普通函数:
>>> def ds (×): return 2* x +1 >>> ds (5) 11
匿名函数:
使用 lambda语句来定义上面函数
>>> lambda x : 2 * x +1
基本语法是使用冒号(:)分隔函数的参数及返回值:冒号的左边放置函数的参数,如果有多个参数,使用逗号(,)分隔即可;冒号右边是函数的返回值。
执行完lambda语句后实际上返回一个函数对象,如果要对它进行调用,只需要给它绑定一个临时的名字即可:
>>> g = lambda x : 2 * x + 1 >>> g(5) 11
6.4.2 filter() 函数
6.4.3 map() 内置函数
map一般作“映射”来解释。map()这个内置函数也有两个参数,仍然是一个函数和一个可迭代对象,将可迭代对象的每一个元素作为函数的参数进行运算加工,直到可迭代序列每个元素都加工完毕
>>> list(map(lambda x : x * 2, range(10))) [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
map()的第二个参数是收集参数。map()会从所有可迭代对象中依次取一个元素组成一个元组,然后将元组传递给func。注意:如果可迭代对象的长度不一致,则以较短的迭代结束为止。
>>> list(map(lambda x, y : x + y, [1, 3, 5], [10, 30, 50, 66, 88])) [11, 33, 55]
6.5 递归
6.5.1 定义:
在函数内部可以调用所有可见的函数,当然也包括它自己。
举例:
>>> def recursion (): recursion () >>> recursion () Traceback ( most recent cal1 last ): File "< pyshell #94>", line 1, in < module > recursion () File "< pyshell #93>", line 2, in recursion recursion () File "< pyshell #93>", line 2, in recursion recursion () File "< pyshell #93>", line 2, in recursion recursion () [ Previous line repeated 990 more times ] RecursionError : maximum recursion depth exceeded
这个例子尝试了初学者玩递归最容易出现的错误。从理论上来讲,这个程序将永远执行下去直至耗尽所有内存资源
次数
Python 3出于“善意的保护”,对递归深度默认是有限制的
如果是编写网络爬虫工具,可能会“爬”得很深。 自行设置递归的深度限制了。方法如下:
>>> import sys >>> sys.setrecursionlimit(10000) # 将递归深度限制设置为一万层
python中%d表示格式化一个对象为十进制整数。使用后,在需要输出的长字符串中占位置。输出字符串时,可以依据变量的值,自动更新字符串的内容。 使用示例:num=14 #%d打印时结果是14 print("num=%d" % num) # output: num=14 #%1d意思是打印结果为1位整数,当整数的位数超过1位时,按整数原值打印,所以%1d的打印结果还是14 print("num=%1d" % num) # output: num=14 #%3d意思是打印结果为3位整数,当整数的位数不够3位时,在整数左侧补空格,所以%3d的打印结果是 14 print("num=%3d" % num) # output: num= 14 #%-3d意思是打印结果为3位整数,当整数的位数不够3位时,在整数右侧补空格,所以%3d的打印结果是14_ print("num=%-3d" % num) # output: num=14_ #%05d意思是打印结果为5位整数,当整数的位数不够5位时,在整数左侧补0,所以%05d的打印结果是00014 print("num=%05d" % n
递归的两个条件: · 调用函数本身。 · 设置了正确的返回条件。
6.5.2 写一个求阶乘的函数
非递归版本:
def recursion ( n ): result = n for i in range (1, n ): result *= i return result number = int ( input (′请输入一个整数:′)) result = recursion ( number ) print ("%d的阶乘是:%d" % ( number , result ))
程序实现结果如下:
>>> 请输入一个正整数:5 5 的阶乘是:120
递归版本:
def factorial ( n ): if n ==1: return 1 else : return n * factorial ( n -1) number = int ( input (′请输入一个整数:′)) result = factorial ( number ) print ("%d的阶乘是:%d" % ( number , result ))
程序实现结果如下:
>>> 请输入一个正整数:5 5 的阶乘是:120
递归函数的实现分析
factorial (5)=5* factorial (4) factorial (4)=4* factorial (3) factorial (3)=3* factorial (2) factorial (2)=2* factorial (1) factorial (1)=1
6.5.3 一帮小兔子——斐波那契数列
斐波那契数列的发明者,是意大利数学家列昂纳多·斐波那契(Leonardo Fibonacci)。当年这个数列是由兔子交配的故事开始讲起的:假如说兔子在出生两个月后,就有了繁殖能力,此后这对兔子在接下来的每个月都能生出一对可爱的小兔子。假设所有兔子都不会老去,就这么一直折腾下去,那么一年以后可以繁殖多少对兔子出来呢?
斐波那契数列
用数学函数来定义,如下:
假设需要求出经历了20个月后,总共有多少对小兔子,不妨考虑一下分别用迭代和递归如何实现?
迭代实现:
#p6_7.py def fab ( n ): a1 =1 a2=1 a3=1 if n <1: print (′输入有误!) return -1 while ( n -2)>0: a3= al +a2 a1=a2 a2=a3 n -=1 return a3 result = fab (20) if result !=-1: print (总共有%d 对小兔子诞生!′ % result )
递归实现:
def fab ( n ): if n <1: print (′输入有误!′) return -1 if n ==1or n ==2: return 1 else : return fab ( n -1)+ fab ( n -2) result = fab (20) if result !=-1: print (′总共有 %d 对小兔子诞生!′ % result )
6.5.4 汉诺塔
印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。 然后不论白天或者黑夜,总有一个僧侣按照下面的法则来移动这些金片:“一次只移动一片,不管在哪根针上,小片必须在大片上面。”规则很简单,另外僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。
思路1,要将64片的金片移到z针上,需要:
(1)将前63个盘子从X移动到Y上,确保大盘在小盘下。 (2)将最底下的第64个盘子从X移动到Z上。 (3)将Y上的63个盘子移动到Z上。
思路2,要将63片金片移到Y针上,需要:
(1)将前62个盘子从X移动到Z上,确保大盘在小盘下。 (2)将最底下的第63个盘子从X移动到Y上。 (3)将Z上的62个盘子移动到Y上。
思路3,…
参考代码:
#p6_9.py def hanoi ( n , X ,Y, Z): if n ==1: print ( X ,'-->', Z ) )#如果只有一层,直接从 x 移动到 Z else : hanoi ( n -1, X,Z, Y) #将前 n -1个盘子从×移动到 Y 上 print ( X ,′-->′, Z ) #将最底下的第64个盘子从 x 移动到 Z 上 hanoi ( n -1, Y , X , Z)#将 Y 上的63个盘子移动到Z上 n = int ( input (′请输入汉诺塔的层数:′)) hanoi ( n ,′ X ',' Y ′,' Z ')
>>> 请输入汉诺塔的层数:3 X --> Z X --> Y Z --> Y X --> Z Y --> X Y --> Z X --> Z
第7章 字典和集合
7.1 字典:当索引不好用时
定义:字典是Python中唯一的映射类型,映射是数学上的一个术语,指两个元素集之间元素相互“对应”的关系
用来检索的这个字(或单词)称为“键(key)”,与其对应的含义称为“值(value)”。
映射类型区别于序列类型,序列类型以数组的形式存储,通过索引的方式来获取相应位置的值,一般索引值与对应位置存储的数据是毫无关系的。
>>> brand = ["李宁", "耐克", "阿迪达斯", "鱼C工作室"] >>> slogan = ["一切皆有可能", "Just do it", "Impossible is nothing", "让 编程改变世界"] >>> print("鱼C工作室的口号是:%s" % slogan[brand.index("鱼C工作室")]) 鱼C工作室的口号是:让编程改变世界
7.1.1 创建和访问字典
用法:
要声明一个空字典,直接用大括号即可:
>>> empty = {} >>> empty {} >>> type(empty) <class 'dict'>
>>>dict1={"李宁":"一切皆有可能丁能","耐克":" Just do it ","阿迪达达斯":" Impossible is nothing ","鱼 c 工作室":"让编程改呈改变世界"} >>>dict1 {李宁:一切皆有可能',!耐克':1Just do it ","阿迪达斯斯':" Impossible is nothing ','鱼 c 工作室':让编程改变世世界′} >>> for each in dict1: print ("% s -> s " % ( each ,dict1[ each ])) 李宁->一切皆有可能 耐克-> Just do it 阿迪达斯-> Impossible is nothing 鱼 c 工作室->让编程改变世界
也可以使用dict()内置函数来创建字典:
>>> dict1 = dict(((′F′, 70), (′i′, 105), (′s′, 115), (′h′, 104), (′C′, 67))) >>> dict1 {′F′: 70, ′i′: 105, ′s′: 115, ′h′: 104, ′C′: 67}
因为dict()函数的参数可以是一个序列(但不能是多个),所以要打包成一个元组(或列表)序列
还可以通过提供具有映射关系的参数来创建字典:
>>> dict1 = dict(F=70, i=105, s=115, h=104, C=67) >>> dict1 {′F′: 70, ′i′: 105, ′s′: 115, ′h′: 104, ′C′: 67}
还有一种创建方法是直接给字典的键赋值,如果键已存在,则改写键对应的值;如果键不存在,则创建一个新的键并赋值:
>>> dict1 {′F′: 70, ′i′: 105, ′s′: 115, ′h′: 104, ′C′: 67} >>> dict1[′x′] = 88 >>> dict1 {′F′: 70, ′i′: 105, ′s′: 115, ′h′: 104, ′C′: 67, ′x′: 88} >>> dict1[′x′] = 120 >>> dict1 {′F′: 70, ′i′: 105, ′s′: 115, ′h′: 104, ′C′: 67, ′x′: 120}
注意
字典不允许同一个键出现两次,如果同一个键被赋值两次,后一个值会被记住:
键必须不可变,所以可以用数值、字符串或元组充当,如果使用列表那就不行了
7.1.2 各种内置方法
7.2.1 创建集合
创建集合有两种方法:一种是直接把一堆元素用大括号({})括起来;另一种是用set()内置函数。
>> set1 = {"小甲鱼", "小鱿鱼", "小鲤鱼", "小甲鱼"} >>> set2 = set(["小甲鱼", "小鱿鱼", "小鲤鱼", "小甲鱼"]) >>> set1 == set2 True
集合在Python中的最大特点就是两个字:唯一。
>>> num = {1, 2, 3, 4 ,5, 4, 3, 2, 1} >>> num {1, 2, 3, 4, 5}
集合是无序的,也就是不能试图去索引集合中的某一个元素:
>>> num [2] Traceback ( most recent call last ): File "< pyshell #57>", line 1, in < module > num [2] TypeError :′ set ′ object does not support indexing
注:在Python 3里,如果用大括号括起一堆数字但没有体现出映射关系,那么Python就会认为这堆数据是一个集合而不是映射。
去重
现在要求去除列表[1, 2, 3, 4, 5, 5, 3, 1, 0]中重复的元素
>>>list1=[1,2,3,4,5,5,3,1,0] >>> temp =list1[:] >>>1ist1.clear() >>> for each in temp : if each not in list1: list1 . append ( each ) >>>list1 [1,2,3,4,5,0]
学习了集合之后,就可以这么写:
>>> list1 = [1, 2, 3, 4, 5, 5, 3, 1, 0] >>> list1 = list(set(list1)) >>> list1 [0, 1, 2, 3, 4, 5]
list()将无序的集合转换成列表,但不能保证原来的列表顺序了
7.2.2 访问集合
由于集合中的元素是无序的,所以并不能像序列那样用下标来进行访问,但是可以使用迭代把集合中的数据一个个读取出来:
>>>set1=(1,2,3,4,5,4,3,2,1,0} >>> for each in setl : print ( each , end =′ ′) 0 1 2 3 4 5
可以使用in和not in判断一个元素是否在集合中已经存在:
>>> 0 in set1 True >>> ′oo′ in set1 False >>> ′xx′ not in set1 True
使用add()方法可以为集合添加元素, 使用remove()方法可以删除集合中已知的元素:
>>> set1.add(6) >>> set1 {0, 1, 2, 3, 4, 5, 6} >>> set1.remove(5) >>> set1 {0, 1, 2, 3, 4, 6}
2.3 不可变集合 frozenset()函数
像元组一样,不能随意地增加或删除集合中的元素
>>> setl = frozenset ({1,2,3,4,5}) >>>set1. add (6) Traceback ( most recent call last ): File "<pyshell#67>",line1, in < module >set1.add(6) AttributeError :' frozenset ' object has no attribute ' add '
使用的是frozenset()函数,就是把元素给frozen(冰冻)起来
第8章 永久存储
8.1 文件:因为懂你,所以永恒
8.1.1 打开文件
open(file, mode='r', buffering=-1, encoding=None, errors=None, newline= None, closefd=True, opener=None)
第一个参数是传入的文件名,如果只有文件名,不带路径的话,那么Python会在当前文件夹中去找到该文件并打开;第二个参数指定文件打开模式
使用open()成功打开一个文件之后,它会返回一个文件对象
>>> # 先在桌面创建一个record.txt的文本文件,内容随意 >>> f = open(r"C:\Users\goodb\Desktop\record.txt") >>>
8.1.2 文件对象的方法
close() 关闭文件
read(size =-1) 文件读取 size 个字符,当未给定 size 或给定负值的时候,读取剩余的所有字符,然后作为字符串返回
readline() 从文件中读取一整行字符串将字符串 str 写入文件
write(str) 将字符串 str 写入文件
writelines(seq) 向文件写入字符串序列 seq , seq 应该是一个返回字符串的可迭代对象
seek(offset , from) 在文件中移动文件指针,从 from ( 0 代表文件起始位置,1代表当前位置,2代 表文件末尾)偏移 offset 个字节
tell() 返回当前文件中的位置
。tell()方法可以告诉你当前文件指针的位置:
8.1.4 文件的读取和定位
read()是以字节为单位读取,如果不设置参数,那么会全部读取出来,文件指针指向文件末尾。 tell()方法可以告诉你当前文件指针的位置:
使用seek()方法可以调整文件指针的位置
>>> f.tell() 284 >>> f.seek(0, 0) 0 >>> f.read(5) ′小客服:小′ >>> f.tell() 9
注意:因为1个中文字符占用2字节的空间,所以4个中文加1个英文冒号刚好到位置9。
readline()方法用于在文件中读取一整行,就是从文件指针的位置向后读取,直到遇到换行符(\n)结束:
>>> f.readline() ′甲鱼,有个好评很好笑哈。\n′
迭代读取文本文件中的每一行
>>> f . seek (0,0) 0 >>>for each_line in f : print ( each_line )
8.1.5 文件的写入
如果需要写入文件,请确保之前的打开模式有'w'或'a',否则会出错:
使用′w′模式写入文件,此前的文件内容会被全部删除。如果要在原来的内容上追加,一定要使用′a′模式打开文件
实例:数据处理
文本: record2.txt
要求:
将文件(record2.txt)中的数据进行分割并按照以下规则保存起来: (1)将小甲鱼的对话单独保存为boy_*.txt文件(去掉“小甲鱼:”)。 (2)将小客服的对话单独保存为girl_*.txt文件(去掉“小客服:”)。 (3)文件中总共有三段对话,分别保存为boy_1.txt、girl_1.txt、boy_2.txt、girl_2.txt、boy_3.txt、girl_3.txt这6个文件(提示:文件中不同的对话间已经使用“=======================================”分割)
参考答案:
count =1 boy =[] girl =[] f = open (r"E:\Python file folder\pylianxi\record2.txt",encoding="utf-8") for each_line in f: if each_line[:6] != ′======′: (role,line_spoken) = each_line.split (′:′,1) if role ==′小甲鱼′: boy.append (line_spoken) if role ==′小客服′: girl.append (line_spoken) else : file_name_boy =′boy_′+ str ( count )+′. txt′ file_name_girl =′girl_′+ str ( count )+′. txt′ boy_file = open ( file_name_boy ,′w′) girl_file = open ( file_name_girl ,′w′) boy_file.writelines ( boy ) girl_file.writelines ( girl ) boy =[] girl =[] count +=1 file_name_boy =′ boy_′+ str ( count )+′. txt ′ file_name_girl =′ girl_′+ str ( count )+′. txt ′ boy_file = open ((r"E:\Python file folder\pylianxi\%s" % file_name_boy),′w′) girl_file = open ((r"E:\Python file folder\pylianxi\%s" % file_name_girl),′w′) boy_file.writelines(boy) girl_file.writelines(girl) boy_file.close() girl_file.close() f.close ()
8.2 文件系统:模块的认识与使用
用法:先使用import语句导入模块,然后再使用。
>>> import random #导入random模块 >>> random.randint(0, 9)#使用randint函数,从0~9的整数中随机读取一位导出 3 >>> random.randint(0, 9) 1 >>> random.randint(0, 9) 8
1.os模块
OS就是Operating System的缩写,意思是操作系统
1)getcwd()
获得应用程序当前的工作目录(用法,如保存临时文件)
>> import os >>> os.getcwd() ′C:\\Users\\goodb\\AppData\\Local\\Programs\\Python\\Python36′
2)chdir(path)
变当前工作目录
如可以切换到E盘:
>>> os.chdir("E:\\") >>> os.getcwd() ′E:\\′
3)listdir(path=′.′)
列举当前目录下有哪些文件和子目录
4)mkdir(path)
mkdir()函数用于创建文件夹,如果该文件夹存在,则抛出FileExistsError异常:
>>> os . mkdir (" test ") >>> os . listdir () ['$ RECYCLE . BIN ',' Arduino ',' System Volume Information ',' test ','工作 室','工具箱','鱼 C 光盘','鱼 C 工作室编程教学'] >>> os . mkdir (" test ") Traceback ( most recent cal1 last ): File "< pyshell #9>",1ine1, in < module > os . mkdir (" test ") FileExistsError :[ WinError 183]当文件已存在时,无法创建该文件。:' test '
5)makedirs(path)
makedirs()函数则可以用于创建多层目录
>>> os.makedirs(r".\a\b\c")
6)remove(path)、rmdir(path)和removedirs(path)
remove()函数用于删除指定的文件
如果要删除目录,则用rmdir()函数
如果要删除多层目录,则用removedirs()函数
>>> # 当前工作目录结构为 ac,b,test.txt >>> os.remove("test.txt") >>> os.rmdir("b") >>> os.removedirs(r"ac") >>> os.listdir() []
7)rename(old, new)
rename()函数用于重命名文件或文件夹:
>> os.listdir() [′a′, ′a.txt′] >>> os.rename("a", "b") >>> os.rename("a.txt", "b.txt") >>> os.listdir() [′b′, ′b.txt′]
8)system(command)
几乎每个操作系统都会提供一些小工具,system()函数用于使用这些小工具:
>>> os.system("calc") # calc是Windows系统自带的计算器
9)walk(top)
作用是遍历top参数指定路径下的所有子目录,并将结果返回一个三元组(路径,[包含目录],[包含文件])
OS.path模块中关于路径常用的函数使用方法
1)basename(path)和dirname(path)
>> os.path.dirname(r"a\b\test.txt") ′a\\b′ >>> os.path.basename(r"a\b\text.txt") ′text.txt′
2)join(path1[, path2[, ...]])
os.path.join()用于将路径名和文件名组合成一个完整的路径
>> os.path.join(r"C:\Users\goodb\Desktop", "FishC.txt") ′C:\\Users\\goodb\\Desktop\\FishC.txt′
3)split(path)和splitext(path)
plit()和splitext()函数都用于分割路径,split()函数分割路径和文件名(如果完全使用目录,它也会将最后一个目录作为文件名分离,且不会判断文件或者目录是否存在);splitext()函数则用于分割文件名和扩展名。
>>> os.path.split(r"a\b\test.txt") ('a\\b', 'test.txt') >>> os.path.splitext(r"a\b\test.txt") ('a\\b\\test', '.txt')
4)getsize(file) getsize()函数用于获取文件的尺寸,返回值以字节为单位。
>>> os.chdir(r"C:\Users\goodb\Desktop") >>> os.path.getsize("record.txt") 284
5)getatime(file)、getctime(file)和getmtime(file)
etatime()、getctime()和getmtime()分别用于获得文件的最近访问时间、创建时间和修改时间。返回值是浮点型秒数,可用time模块的gmtime()或localtime()函数换算:
>>> temp = time.localtime(os.path.getatime("python.exe")) >>> print("python.exe 被访问的时间是:", time.strftime("%d %b %Y %H:%M:%S", temp)) python.exe 被访问的时间是: 27 May 2015 21:16:59 >>> temp = time.localtime(os.path.getctime("python.exe")) >>> print("python.exe 被创建的时间是:", time.strftime("%d %b %Y %H:%M:%S", temp)) python.exe 被创建的时间是: 24 Feb 2015 22:44:44 >>> temp = time.localtime(os.path.getmtime("python.exe")) >>> print("python.exe 被修改的时间是:", time.strftime("%d %b %Y %H:%M:%S", temp)) python.exe 被修改的时间是: 24 Feb 2015 22:44:44
8.3 pickle
使用这个模块,就可以非常容易地将列表、字典这类复杂数据类型存储为文件了
几乎可以把所有Python的对象都转化为二进制的形式存放,这个过程称为pickling,那么从二进制形式转换回对象的过程称为unpickling
#p8_3.py import pickle my list =[123,3.14,′小甲鱼′,[′ another list ′]] pickle file = open (′ E :\\ my list . pkl ′,′ wb ′) pickle . dump ( my _ list , pickle _ file ) pickle file . close ()
#p8_4.py import pickle pickle _ file = open (" E :\\ my _ list . pkl "," rb ") my _ list = pickle . load ( pickle file ) print ( my list )
第9章 异常处理
9.1 异常集合
FileNotFoundError异常
用户输入一个不存在的文件名
1)AssertionError:断言语句(assert)失败
当assert这个关键字后面的条件为假时,程序将停止并抛出AssertionError异常
2)AttributeError:尝试访问未知的对象属性
3)IndexError:索引超出序列的范围
在使用序列的时候就常常会遇到IndexError异常,原因是索引超出序列范围的内容:
4)KeyError:字典中查找一个不存在的关键字
当试图在字典中查找一个不存在的关键字时就会引发KeyError异常,因此建议使用dict.get()方法:
>>> my _ dict ={" one ":1," two ":2," three ":3} >>> my _ dict [" one "] 1 >>> my _ dict [" four "] Traceback ( most recent call last ): File "< pyshell #10>", line 1, in < module > my _ dict [" four "] KeyError :′ four ′
5)NameError:尝试访问一个不存在的变量
6) OSError:操作系统产生的异常
OSError,顾名思义就是操作系统产生的异常
7)SyntaxError:Python的语法错误
>> print "I love fishc.com" SyntaxError: Missing parentheses in call to 'print'. Did you mean print("I love fishc.com")?
8)TypeError:不同类型间的无效操作
9)ZeroDivisionError:除数为零
9.2 try-except语句
y-except语句用于检测和处理异常
检测是否打开一个不存在的文件,如果出错了,就会提示
但是从程序员的角度来看,导致OSError异常的原因有很多(如FileExistsError、FileNotFoundError、PermissionError等),所以可能会更在意错误的具体内容,这里可以使用as把具体的错误信息给打印出来
except OSError as reason : print (′文件出错啦 T T \ n 错误原因是:′+ str ( reason ))
9.3 try-finally语句
如果try语句块中没有出现任何运行时错误,会跳过except语句块执行finally语句块的内容。如果出现异常,则会先执行except语句块的内容再执行finally语句块的内容。
9.4 raise语句
用raise语句可检测语句,抛出一个异常:
9.5 丰富的else语句
对于大多数编程语言来说,else语句都只能与if语句搭配。但在Python里,else语句的功能更加丰富。 在Python中,else语句不仅能与if语句搭配,构成“要么怎样,要么不怎样”的句式;它还能与循环语句(for语句或者while语句)
9.6 简洁的with语句
Python提供了一个with语句,利用这个语句抽象出文件操作中频繁使用的try/except/finally相关的细节。
使用with语句,可以改成这样:
第10章 图形用户界面入门
10.1 安装EasyGui
第11章 类和对象
第12章 魔法方法
第13章 模块
第14章 论一只爬虫的自我修养
第15章 正则表达式
第16章 Scrapy爬虫框架
第17章 GUI的最终选择:Tkinter
第18章 Pygame:游戏开发