python之代码简化式(列表、字典生成式,递归函数,迭代器(iter)和生成器(yield)、匿名函数(lambda)的使用)(12)

前言

本文主要讲解一些简化代码格式的一些方法,方便大家更好的完成各种程序的开发;其中包括列表、字典生成式,递归函数,迭代器(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}
方法2for 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不同的是:

  1. 在函数中出现return会立即退出,而 yield出现在函数中表示暂停,直接调用函数不会执行;必须使用 next(函数名()) 来调用
  2. print(next(b)) 表示调用函数,执行到第一个yield后暂停;若yield后有返回值就输出,没有就输出None;相当于return
  3. 再次执行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]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

盲敲代码的阿豪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值