文章目录
前言
本文主要讲解一些简化代码
格式的一些方法,方便大家更好的完成各种程序的开发;其中包括列表、字典生成式,递归函数,迭代器(iter)和生成器(yield)以及匿名函数(lambda)
的使用
1、列表、字典生成式
通过简短的代码对
可迭代数据类型
(列表、元组等)中的元素进行处理,然后快速
生成一个列表或字典
语法格式:变量 = [代码 for 变量 in 数据]
下面我直接通过案例讲解
- 案例1:快速生成列表(偶尔会使用)
list = ['ah','hh','lalala'] # 将该列表中的元素全部转换成大写字母
# 传统方法
new = []
for x in list:
new.append(x.upper())
print(new) # 输出结果:['AH', 'HH', 'LALALA']
从上面可以看到,在原来当我们将一个列表中的元素全部转换成大写字母,需要使用好几行的代码才能解决;但通过列表生成式
我们只需一行代码
即可解决;如下:
list = ['ah','hh','lalala']
# 新方法
new = [x.upper() for x in list] # 列表生成式
print(new) # 输出结果:['AH', 'HH', 'LALALA']
说明:
从上面可以看,我们可以直接在中括号[]
中直接使用for循环的代码
对列表元素进行处理,并将处理好的元素依次加入新的列表
中,最后得到的结果与传统方法
相同,并且简化了代码
- 案例2:快速生成字典(基本用不到)
list = [('name','ah'),('age',18),('sex','man')] # 将该列表转换成字典
# 传统方法
new = {}
for a,b in list:
if a != 'sex':
new[a] = b
print(new)
使用字典生成式完成上面的需求:
new = {a:b for a,b in list if a!='sex'} # 字典生成式
print(new)
总结:
上面两种方法的作用都是简化代码的书写过程,没有实际意义,且可读性较差,在日常开发中,还是以传统方法为主
2、递归函数
在调用函数的过程中,
直接或间接
的调用了自己,以达到循环
的效果
- 案例1:直接调用
def a():
print(666)
a() # 2、重复调用函数a
a() # 1、调用函数a
- 案例2:间接调用
def a():
b() # 2、调用函数b
def b():
a() # 3、继续调用函数a
a() # 1、调用函数a
总结:
从上面可以看到,我们可以通过函数递归的方式,使函数重复运行,达到循环的效果;所以python中使代码重复执行的方法可以有:
1、while或for循环
2、递归函数
2.1 python中代码的递归深度(扩展)
在前面学习
while和for
循环的时候,我们知道在日常开发中要避免死循环
的现象;一般我们会通过设置条件
来避免死循环;而python中也自带了一个保护机制
;用来控制代码的递归次数
;以免大量占用电脑内存,造成死机
- 通过设置条件,避免函数递归陷入死循环
def a(n):
if n<5:
print(n)
n = n+1
a(n)
a(1)
输出结果:
1
2
3
4
- 设置python的代码递归次数,避免死循环
python默认的最大递归次数是1000,这个次数可以通过命令修改,但不建议修改;只需了解一下修改的方法;如下:
# 调用sys模块
import sys
# 设置最大递归次数
sys.setrecursionlimit(100)
# 查看最大递归次数
print(sys.getrecursionlimit()) # 输出结果:100
案例:
# 调用sys模块
import sys
# 设置最大递归次数
sys.setrecursionlimit(5)
def a():
print(666)
a()
a() # 死循环
输出结果:
说明:
从上面可以看到,设置最大递归次数为6;死循环在循环6次后就会直接报错;而默认的情况下,要循环1000次后才会报错
3、拓展:迭代器和生成器
3.1 迭代器(iter)
将
可迭代对象转换成迭代器
,通过内置方法调用迭代器,能够依次得到可迭代对象中的元素
可迭代对象包括:列表、字典、元组、字典、集合、打开的文件对象
语法格式:
1、生成迭代器:迭代器 = iter(可迭代对象)
,这里迭代器就是一个变量
2、调用迭代器:next(迭代器)
案例1:迭代列表
a = [1,2,3]
text1 = iter(a) # 生成迭代对象
print(text1) # 输出结果:<list_iterator object at 0x000002334C0810D0>
print(next(text1)) # 输出结果:1
print(next(text1)) # 输出结果:2
print(next(text1)) # 输出结果:3
说明:
从上面可以看到,将列表a 转换成迭代器
后,直接打印迭代器 text1
得到的是一个地址;然后通过 next()
方法每执行一次,都会得到列表a中的下一个
元素;注意
执行次数超过列表中的元素就会报错
案例2:迭代字典
b = {'name':'阿豪','age':18}
text2 = iter(b)
print(next(text2)) # 输出结果:name
print(next(text2)) # 输出结果:age
说明:
从上面可以看到,字典转换成迭代器后,每执行一次 next()
,都会得到字典中的下一个键
;注意
执行次数超过字典中的键值对就会报错
- 总结
迭代器
其实就是for循环的底层原理之一,我们知道for循环是while循环扩展扩展出来的一种简便方法;它集成了 迭代器、while循环、异常处理等语法
案例:
a = {'name':'阿豪','age':18}
# 方法1:
b = iter(a)
while True:
try: # 异常处理,用于解决next执行超过次数报错问题
print(next(b))
except StopIteration:
break
等同于:
a = {'name':'阿豪','age':18}
方法2:
for x in a:
print(x)
输出结果:
name
age
说明:
从上面可以看到,两种方法的结果相同,方法2中for循环在执行时,相当于运行了方法1中的代码;明白这个道理后,我们可以更好的运用所学知识点
3.2 生成器(yield)
自定义的一种迭代器,放在函数中使用,作用与return相似
语法格式:
1、定义
def 函数名():
代码
yield 返回值
2、调用
next(函数名())
案例:
def a():
print('第一') # 第一个next
yield # 没有返回值,得到 None
print('第二') # 第二个next
yield 666 # 有返回值,得到 666
print('第三') # 第三个 next
yield # 没有返回值,得到 None
a() # 直接调用,没有任何结果
b = a() # 将 a() 绑定给 变量b
print(next(b)) # 输出结果: 第一 None
print(next(b)) # 输出结果:第二 666
print(next(b)) # 输出结果:第三 None
- yield的使用说明
yield 只能在函数中使用,与return不同的是:
- 在函数中出现
return
会立即退出
,而yield
出现在函数中表示暂停
,直接调用函数不会执行;必须使用next(函数名())
来调用print(next(b))
表示调用函数,执行到第一个yield后暂停
;若yield后有返回值就输出,没有就输出None
;相当于return- 再次执行
print(next(b))
,代码会从上次暂停的 yield后继续运行
,遇到 yield又暂停;重复这个步骤,有多少yield就可以调用几次;当 next(b) 找不到yield后就会报错
- yield 主要应用场景:读取大文件
案例:
def get():
with open('1.jpg','rb') as f:
while True:
res = f.read(10) # 每次读取10个字节
if res:
yield res # 返回读取的10个字节并暂停
else:
break # 没有内容后就退出循环
print(next(get())) # 得到第一次读取的内容
print(next(get())) # 得到第二次读取的内容
说明::
在读取大文件时,若直接读取会占用大量内存,而通过yield可以实现一段段的读取,读取一次暂停一次,每次只读取一部分内容;这样能够节省内存
4、匿名函数(lambda)
没有名字的函数,用特殊格式定义,可以执行简单的代码,主要配合其它函数使用
案例:
# 传统函数
def a(x,y):
return x+y
print(a(1,2)) # 输出结果:3
等同于
# 用匿名函数实现上面的代码
# 1、定义函数
b = lambda x,y:x+y # 定义后绑定给变量b
# 2、调用函数
print(b(1,2)) # 方法1:通过变量b传参
print((lambda x,y:x+y)(1,2)) # 方法2:直接使用函数体传参
# 输出结果:3
总结:
匿名函数结构简单,只能执行上面这种简单的代码,主要是配合接下来学习的几种函数,我们往下看
4.1 map函数
通常用来对
可迭代对象
中的元素做一些处理,可迭代对象包括:字符串、列表、字典、元组、集合等等
语法格式:map(参数1,参数2)
map函数可接收两个参数:
参数1:函数
,这里的函数通常为匿名函数
参数2:可迭代对象
案例:
a = [1,2,3,4,5] # 可迭代对象
# 对列表a中的元素做平方处理
res = map(lambda x:x**2,a) # x为参数用于接收 列表a中的每个元素,x**2表示对每个元素平方
print(res) # 直接打印得到是一个map对象地址
print(list(res)) # 这里我们用list方法,将其转换成列表显示
输出结果:
<map object at 0x000001B30E3918B0>
[1, 4, 9, 16, 25] # 每个元素都平方了
4.2 reduce函数(较少使用)
对
可迭代对象中
的元素进行累加
操作
需要调用模块:from functools import reduce
语法格式:reduce(函数,可迭代对象)
案例:
from functools import reduce # 调用模块
array = [1,2,3,4,5] # 可迭代对象
res = reduce(lambda x,y:x+y,array) # 相当于 1+2+3+4+5 = 15
print(res) # 输出结果:15
说明:
上面匿名函数,lambda x,y:x+y
,其中 x,y
分别接收 1,2
;相加后得到3;然后x,y又分别接收 3,3
相加后得到6,然后x,y又分别接收 6,4 ,相加得到10,重复该步骤 对列表中的元素进行累加,相当于 1+2+3+4+5 = 15
4.3 filter函数
通过条件筛选
可迭代对象
中的元素
语法格式:filter(函数,可迭代对象)
案例:
array = [1,2,3,4,5]
res = filter(lambda x:x>3,array) # 筛选列表中大于3的元素
print(list(res)) # 输出结果:[4,5]