Python知识梳理(二)
Day6:控制流
- 控制流就是控制程序的运行方向,符合条件的代码执行,不符合的不执行;程序代码是从上到下执行,从左到右执行,和人的行为习惯是类似;
- 控制流分为
顺序控制流
、分支控制流
、嵌套控制流
、循环控制流
; 顺序控制流
的基本语法为:if...else
,条件满足执行if的条件代码块,否则执行else的代码块;分支控制流
就是在顺序控制流if...else
的基础上,在if和else的中间加上不定量的elif
,可以加入多个elif,执行顺序是自上而下,满足条件则执行;嵌套控制流
,顾名思义就是在控制流的语句里面里面嵌套一个或者多个控制流,比如:if顺序里面再嵌套新的if顺序控制流,建议不要嵌套太深,一般不大于3层以上为佳,执行顺序依旧是自上而下,满足条件则执行;循环控制流
分为四种情况:
(1) while循环 就是在某条件下,循环执行某段程序,多用于处理需要重复处理的相同任务
while 判断条件:
执行语句
(2) while...else循环 和while循环的不同在于,它会在循环正常执行完毕后执行 else 语句块中的代码
(3) for循环可以遍历任何序列的项目,如一个列表或者一个字元串
(4) for...else循环和while...else循环一样,会在循环正常执行完毕后执行 else 语句块中的代码
(5) while...else和for...else如果循环代码中有break、return、或者错误产生的时候,不会执行其else语句哦。
循环控制流需要注意,循环需要有结束循环的条件,否则无限执行就会耗尽资源而导致代码崩溃中止。
continue 语句
表示跳出本次循环,继续进行下一轮循环break语句
表示跳出整个循环,即循环条件没有False条件或者序列还没被完全递归完,也会停止执行循环语句- 一般来说,0、"" 空字元串、() 空元组、[] 空列表、{} 空字典、None 等空值的都为False,而像 1、"Str" 字元串等有值的都为True
Day13:容器类型结构的封装和解构
- 能够装载元素的数据结构就可以定义为
容器类型的数据结构
,也就是可以往里面放数据的,如整数类的数据,就不能往里面放数据了,那么就不是容器类数据; - 容器类型的数据结构包括:
list列表,tuple元组,set集合,dict字典
; 封装
表示通过逗号对多个元素进行组装,组合在一起,本质上返回的是一个元组,只是省略了小括弧;解构
则是将元素从容器类型的数据结构分离出来,在解构时候,左右两边的元素个数必须一一对应;- 解构时可以使用可变位置参数接收多个元素, args收集剩余的元素且组装成一个列表;
- 也可以在解构的时候将不需要的元素使用_来接收;
- 封装和解构可以快速的构建我们需要的数据,比如:a, _, _, _ = (首页,产品,地图,联系),我想获取第一个元祖的元素,a这样就很方便得到;
Day15:解析式与生成器
- 解析式主要是用来减少编程行数,并减少栈帧从而达到代码优化的效果,也就是把原本要几行的代码实现的功能,通过使用解析式一行代码就可以实现,解析式可以提升代码质量,但针对Python新手可能不太适应,大家可以选择性的先了解一下这些解析式,以后熟练了再使用也是可以的。
- 列表解析式
(1) 列表解析式是将数据全部存储在内存中一并返回
(2) 列表解析是Python迭代机制的一种应用,它常用于实现创建新的列表,因此使用中括弧[]表示
(3) 使用列表解析式不会因为简写而影响效率,反而优化提升效率,减少代码量,可读性强,工作量降低,
减少出错
- 集合解析式
集合解析式和列表解析式用法一样,只是集合解析式使用大括弧{}表示
- 字典解析式
字典解析式使用大括弧{}表示,并且要有两个表达式:一个生成key,一个生成value;
两个表达式之间使用冒号分隔,返回结果是字典
- 生成器
1.在Python中,这种一边循环一边计算的机制,称为生成器(Generator)
2.语法:g = (item for item in range(10)),和列表解析式很类似,只是最外层为(),不是[]
3.生成器的特点是按需计算,惰性求值,最大可能的节约内存空间。比如:1万条列表数据,
我只需要读取里面的几条,如果直接用for循环这些数据的话,就会把这些数据一次性装进内存,
导致占据大量资源,这个时候,使用生成器,那么就可以做到我需要那几条,就把那几条装进内存来求值
4.生成器是可迭代对象,取值完毕之后,无法再次取值,它有两种取值方式,一种是通过next获取值,
这种方式取值时如果取值的次数超过生成器对象值的长度,就会报错,需要传入None参数。
5.还有一种是通过for循环取值,通过这种方式取值时如果取值的次数超过生成器对象值的长度,for循环会通知
迭代,所以不会报错,我们一般使用for来进行循环获取。
Day16:函数
- 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段
- 定义函数的语法为:
def 函数名称(参数)
,它的规则如下:
1.函数代码块以 def 关键词开头,后接函数标识符名称和圆括弧()
2.任何传入参数和自变数必须放在圆括弧中间,圆括弧之间可以用于定义参数
3.函数的第一行语句可以选择性地使用文档字元串(用于存放函数说明)
4.函数内容以冒号起始,并且缩进
5.return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的return相当于返回 None
- 实现了
__inter__()
方法的对象就叫做可迭代对象,可迭代对象包括:list、tuple、string、bytes、bytearray、range、set、dict等,可迭代简单理解为就是可以使用for来循环的对象; - 实现了
__next__()
方法的对象都是迭代器,迭代器的特点和生成器很像,特别适合迭代大量数据,惰性求值。生成器就是迭代器,但迭代器不一定是生成器 - 默认参数
当一个函数中的某个参数的改动不大,就可以考虑将这个参数设置为默认参数
默认参数在一个函数中可以有多个,且默认参数必须放在位置参数后面
- 位置参数:函数定义的参数位置来传递参数,如第1个参数为位置参数,调用的函数时候就第一位传入,如:add(1,2,34)
- 关键字参数:在函数调用的时候,通过「键=值」形式指定参数,键就是定义函数的是参数名字,可以让函数更加清晰易用,同时,参数的位置可以不需要按位置顺序,如:add(x=1, y=2, z=3)。
位置参数可以和关键字参数一起使用,但是位置参数必须在关键字参数之前,如:add(1, z=2, y=3)
- 可变参数
1.可变参数就是表示传入的参数个数是可变的,可以一个也可以多个参数,它包括可变位置参数和可变关键字参数
2.可变位置参数(一个*+参数名)就是把参数封装成一个元组,然后在元组里面迭代
3.可变关键字参数(两个**+参数名)把参数构成一个key-value键值对组成的字典
- 可变位置参数和关键字参数的使用注意
前面有可变位置参数收集参数,后面的所有参数必须使用关键字参数传值,如下Python:
应该这样调用:add(1,2,3, k=6),不要这样调用:add(1,2,3,6)
def add(*args, k):
print(*args, k)
- 参数的封装与解构
参数封装就是在调用函数的时候,把本应传入多个参数的数据封装成一个元祖或者字典,更加简便
解构就是把封装成的元组或者是字典的数据解成单个的值,符合函数参数的需求
*号是解构元组,**号是解构字典
示例一:如下函数add(),需要传入x、y参数,按正常做法是add(1,2)这样,但是我的数据是元祖也就是传入add((1,2)),
但是这样的话,就相当于只传入了x这个参数,我们通过*(1,2)这样就可以把这个元祖解构为1,2这样的数据了:
def add(x, y):
print(x, y)
add(*(1,2))
示例二,字典的示例:
def add(x=1, y=2):
print(x, y)
add(**{x:100, y:200})
Day17:函数的返回值与嵌套函数
- 返回值指的是函数返回的结果
当return语句执行完毕,后面的语句将不会再执行
如果一个函数里面有两个return,前面return执行完毕,后面的return也不会执行,如:
def add(x, y):
print(x, y)
return x + y
return x - y
- 函数体内没有return语句的,称为隐式返回(默认返回None),有return语句,称为显示返回(直接返回结果)
- 函数可以返回多个值
将这些值通过逗号分开,会把值进行压缩,封装成一个元组,如:return x,y,z得到结果是元祖:(x,y,z)
而如果返回一个列表,得到的就是一个列表
- 嵌套函数,顾名思义就是函数内部还有函数
且内部函数只能在包含它的函数的直接父级调用,也就是只能在直接包含它的外部函数中调用
嵌套函数层数不宜过深,一般3层以内即可,太深不够直观,容易造成代码混乱
- 作用域指的是,一个标识符(也就是函数或者变数)的作用范围就是这个函数或者变数的作用域
在函数外部定义的变数,即全局作用域,在函数体外部和内部都能被访问
在函数里面定义的变数,即局部作用域,只能在函数体内部被访问,函数外部不能访问
- 闭包:内部函数引用了外部函数的变数,外部函数把内部函数作为返回结果,如:
def outer():
def inner(a):
print(a)
return inner
func = outer()
func(1)
func得到的是inner这个函数引用,需要调用
闭包的理解:
就是在函数a里面再嵌套一个函数b等,那么函数b里面都可以引用函数a的变数,然后函数a返回值是函数b,
这样就形成了闭包
如果要访问函数体内部的函数,可以先把内部函数的函数名作为外部函数的返回值,把外部函数的引用赋值给
变数,再调用变数,这就是闭包
- global关键字:可以指定变数为全局变数,但是global关键字会污染全局变数,也就是会覆盖之前全局变数的值,所以最好慎用
- nonlocal关键字:可以申明内部函数的变数引用的是外部函数变数的值(作用域在外部函数),不是全局作用域的值,因此不会污染全局作用域
- 函数默认值的作用域
同一个函数的生命周期相同,函数的默认值会绑定在函数的整个生命周期上,不会因为函数内部对默认值的操作
而发生改变
函数默认值,如果进行修改后,默认值会发生改变,这个时候可以使用浅拷贝copy模块的copy()函数(简写[:])来清空默认值,
那每次调用函数,默认值都为初始值。如:
def add(lst = []):
lst = lst[:]
# lst = copy.copy(lst)
lst.append(hello)
print(lst)
add()
add()
也可以通过参数值判断来给默认值重新赋值,那每次调用函数,默认值都为初始值
- 函数运行结束时,使用del 删除函数对象,释放计算机资源占用,如:
def add():
print(add)
del add
Day18:递归函数与匿名函数
- 调用自己本身的函数叫递归函数
- 前两项都是1,第三项开始,每一项都是前两项之和的数列是斐波那契数列
- 递归函数的特性
1.递归一定需要有结束条件
2.每次进入更深一层递归时,问题规模比上一次递归都应有所减少
3.通常前一次递归的输出就作为后一次递归的输入
4.递归效率不高,递归层次过多会导致栈溢出
- 没有名字的函数就是匿名函数
因为匿名函数没有名字,所以不必担心函数名冲突,匿名函数可以实现自调用
在Python中,通常借助lambda表达式构建匿名函数,关键字lambda表示匿名函数,冒号前面的变数名表示函数参数,
如:
fn = lambda x: x+1
调用:fn(3)
Day19:生成器函数
- 生成器函数指的是函数体中包含yield关键字的函数,它也是一个函数,和普通函数区别就是yield关键字(可以结合Day15中的生成器理解),如:
def gen():
print(line 1)
yield line 1
print(line 2)
yield line 2
print(line 3)
yield line 3
g = gen()
print(g)
next(g)
next(g)
yield就相当于专门给生成器用的return,可以理解每次next()迭代读取一个yield之前的代码来执行
生成器可以通过生成器表达式和生成器函数获取到
我们可以通过yield关键字来定义一个生成器函数,这个生成器函数返回值就是一个生成器对象
生成器函数也是用于惰性计算,相当于把函数分为多次执行。
- 生成器函数可以使用next()迭代,且每次next()只会返回一次yield的值,然后暂停,下次一次next()时会在当前位置继续,如果没有元素可以迭代了,还执行next()则需要给定一个默认值,不给默认值会报错
- 如果在生成器函数中使用return,则会终止迭代,且不能得到返回值
- 在生成器中使用死循环,不会一直执行,仍旧是执行多少次next(),返回多少个值
- 生成器函数中的语法糖(可以先行理解,暂不要求熟练使用)
语法糖指那些没有给计算机语言添加新功能,而只是对人类来说更加易于使用和理解的语法
语法糖给程序员提供了更实用的编码方式,有益于更好的编码风格,更易读
生成器的语法糖也就是生成器的一种语法,作用是使代码更加简洁
Day20:高阶函数
- 一个函数可以作为参数传给另外一个函数,或者一个函数的返回值为另外一个函数(若返回值为该函数本身,则为递归),满足其一则为高阶函数,本节课程稍微有点抽象,要求掌握好标准库中的:
sorted、filter、map
这几个高阶函数的使用。 - sorted函数:
sorted(iterable[, key][, reverse])
1.sorted是Python提供的功能强大的排序函数,满足字元、数字等排序要求
2.函数的第一个参数为可迭代对象,第二个参数key作为排序的规则(指定按什么排序),
第三个参数表明是否反向
3.sorted函数的返回结果是列表类型
- filter函数:
filter(function, iterable)
1.filter函数也是接收一个函数和一个序列的高阶函数,其主要功能是过滤
2.第一个参数是一个函数,第二个参数是可迭代对象
3.filter函数的返回值是迭代器对象filter
- map函数:
map(func, *iterables)
1.map函数用来将序列中的值处理再依次返回至列表内
2.第一个参数func为函数,实现函数映射的功能,第二个参数为可迭代对象
3.map函数的返回值为一个迭代器对象map
来自:https://www.9xkd.com/user/plan.html
推荐阅读: