Python进阶(四)----生成器、列表推导式、生成器推导式、匿名函数和内置函数

mac2022-06-30  83

Python进阶(四)----生成器、列表推导式、生成器推导式、匿名函数和内置函数

一丶生成器

本质:

​ 就是迭代器

生成器产生的方式:

​ 1.生成器函数 ?

​ 2.生成器表达式 ?

​ 3.python内置函数或者模块提供(其实1,3两种本质上差不多,都是通过函数的形式生成,只不过1是自己写的生成器函数,3是python提供的生成器函数 如: map() filter() zip()等等)

生成器与迭代器的区别:

​ 生成器是我们自己用python代码构建的.迭代器可以使用iter() , __ iter __()进行取值

二丶生成器函数

####只要函数中出现了yiled ,那么就是一个生成器函数.(生成器) ## 一个next 对应一个yield def func(): #当出现了yiled就是不再是函数了就是生成器函数 print(111) print(111) print(111) print(111) yield 2 # yield的作用是,yield后面的值 给了next取值 yield 3 yield 4 yield 5 ret=func() # 生成器对象 赋给变量ret print(ret) # 生成器对象地址 <generator object func at 0x0000018ACC20EF68> print(ret.__next__()) # ret执行__next__()方法 取值 2 print(ret.__next__()) # ret执行__next__()方法 取值 3 print(next(ret)) # ret执行__next__()方法 取值 4 next()方法的本质还是__next__() print(next(ret)) # ret执行__next__()方法 取值 5 print(next(ret)) # 当 生成器对象中没有值可以取的时候就会报错---> StopIteration

三丶yiled与return的区别

return:

​ 结束函数,给函数的执行者返回值,多个值通过元组返回,

yiled:

​ 不结束函数 ,(暂停函数) . 对应着给next返回值 , 多个值通过元组返回

# return def func(): return 1,2,3,4 print(func()) # yield def func(): yield 1,2,3,4 # yield后面跟一个列表就返回一个列表,返回多个值就是返回一个元组 print(func().__next__())

四丶send(了解)

# next只能获取yield生成的值,但是不能传递值。 def gen(name): print(f'{name} ready to eat') while 1: food = yield print(f'{name} start to eat {food}') ​ dog = gen('alex') next(dog) next(dog) next(dog) ​ ​ # 而使用send这个方法是可以的。 def gen(name): print(f'{name} ready to eat') while 1: food = yield 222 print(f'{name} start to eat {food}') ​ dog = gen('alex') next(dog) # 第一次必须用next让指针停留在第一个yield后面 # 与next一样,可以获取到yield的值 ret = dog.send('骨头') print(ret) ​ ​ def gen(name): print(f'{name} ready to eat') while 1: food = yield print(f'{name} start to eat {food}') ​ dog = gen('alex') next(dog) # 还可以给上一个yield发送值 dog.send('骨头') dog.send('狗粮') dog.send('香肠') ############# 此处, 先看看, 之后会补充含义 #send和next()区别: # 相同点: # send 和 next()都可以让生成器对应的yield向下执行一次。 # 都可以获取到yield生成的值。 # 不同点: # 第一次获取yield值只能用next不能用send(可以用send(None))。 # send可以给上一个yield置传递值。

五丶生成器的应用

##生成器应用 ,现在你需要一个服装工厂给你加工2000件衣服, ###可迭代对象 #老板很实在,一下给你准备好了2000件衣服 def func() li=[] for i in range(1,2001): li.append(f'{i}件衣服') return li print(func()) # 老板的工厂中一半的场地都用来堆积2000衣服 # 总结, 加工2000个衣服, 假如说加工一件1秒, 你现在需要2000秒才能加工完成. 而且加工完的衣服必须有地方放置. 耗时耗空间. 但是比较很直观,2000个衣服就在工厂里囤放. 换到程序角度来说: 你需要2000条数据,你的内存中就存放了2000个数据. 不管你用多少,这2000条数据就会在内存是实实在在的占2000个位置. so 占内存大. ###生成器 #加工厂老板,给你准备好了加工衣服的传送带, 夸张一些加工一件衣服1秒. def func(): #生成器函数, 相当于创建一个加工流水线 for i in range(1,2001): yield print(f'{i}件衣服') #yield返回数据, 相当于把加工的衣服给来拿衣服的你 gen_obj = func() #把生成器给了一个变量, 确保每次来加工时,都是这个流水线(预定) ###需求: 现在你需要200件衣服,老板立马给你制作了200件衣服 ,剩下的1800件还在待加工的状态. for i in range(200): # 你拿了200件 ,执行了200次拿的动作 gen_obj.__next__() # 在当前的这个流水线(当前的这个生成器),每次拿一件(每次取一个数据) ###需求: 现在你需要400件衣服,老板立马从剩余的1800件衣服中又制作了400件衣服给你,现在这个流水线还剩1200 for l in range(400): # 老板从你预定的流水线继续加工400件 next(gen_obj) # 还是在当前的这个流水线(当前的这个生成器),每次拿一件(每次取一个数据) # 总结, 你预定了2000件衣服, 老板没有给你一起直接加工出来,每当你来拿衣服的时候你需要多少个,老板给你咔咔咔把你需要多少个衣服加工出来. 优势:1.对于老板的工厂来说,不占地方, (对于程序来说,不占内存,需要多少条,就生成多少条,内存中就占这么多,并且一点数据取出来(next)就销毁.) 2.对加衣服的你也没有影响.(不影响本身程序的调用) ##创建200个生成器函数 --->相当于创建了200流水线 for i in range(200): # 生成200个生成器函数 print(func().__next__(),type(func())) # 所以每次打印的都是 1

六丶yiled与yiled from

##yield def func(): li=[1,2,3,4] yield li # yield 返回一个值 , 若是yield后跟多个值,就以元组的形式返回 ret =func() print(next(ret)) # 返回一个列表的值(只能得到一个值,next只接一次,不管你是元组 或 列表都是一个值返回) print(next(ret)) # 报错 StopIteration ##yield from 可以把 后面的可迭代的对象进行拆分,依次给next取值. def func(): li=[1,2,3,4] yield from li # yield from 把可迭代对象拆分, 简化for循环, ''' #表面现象 yield 1 yield 2 yield 3 yield 4 ''' ret =func() print(next(ret)) # 1 print(next(ret)) # 2 print(next(ret)) # 3 print(next(ret)) # 4 #### yield 与yield from 对比 #### # yield : 对应next ,给next 返回值 # yield from 将一个可迭代对象的每一个元素返回给next # yield from 节省代码 ,提升效率

七丶列表推导式,生成器表达式(字典的推导式,集合推导式)

列表推导式:

​ 一行代码构建一个有规律比较复杂的列表。(?看代码.不废话)

####两种构建方式: # 1.循环模式: [变量(加工后的变量) for 变量 in iterable] # 2.筛选模式: [变量(加工后的变量) for 变量 in iterable if 条件] ######循环模式 ##需求:循环 100以内的所有的值 #平常做法 li=[] for i in range(1,101): li.append(i) print(li) #列表推导式 print([i for i in range(1,101)]) ######筛选模式 复杂程度不能超过3级 ##案例1:三十以内可以被2整除的数。 print([i for i in range(1,31) if i%2==0]) #案例2: 找到嵌套列表中名字含有两个‘e’的所有名字(有难度) names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] ##普通做法 li=[] for el in names: for el2 in el: if el2.count('e')>=2: li.append(el2) print(li) ##列表推导式 print([name for el in names for name in el if name.count('e')>=2]) ####列表推导式的优缺点 #优点:简单 快捷 #缺点:可读性不高,不好拍错 # 慎用,不用入迷

生成器表达式:

​ 一行代码构建一个生成器。(?看代码.不废话)

####两种构建方式: # 1.循环模式: (变量(加工后的变量) for 变量 in iterable) # 2.筛选模式: (变量(加工后的变量) for 变量 in iterable if 条件) ####循环模式 obj=(i for i in range(10)) print(obj) #<generator object <genexpr> at 0x000001972E9CEF68> #如何触发生成器(迭代器 )取值? # 1. next() , __next__() 逐个取值 # 2 . for 循环 遍历取值 哪个简单不用多说了吧 # 3 . list for i in obj: print(i) ####筛选模式 obj=(i for i in range(10) if x%2==0) print(obj) #<generator object <genexpr> at 0x000001999105FF68>

字典的推导式: (创建模式同上?,一行解决)

####两种构建方式: # 1.循环模式: {变量(加工后的变量) for 变量 in iterable} # 2.筛选模式: {变量(加工后的变量) for 变量 in iterable if 条件} li= ['小潘', '第三部','金馆长', '宋老板'] #普通创建字典 dic={} for k,i in enumerate(li): dic[k]=i print(dic) #字典推导式 print({k:i for k,i in enumerate(li)})

集合推导式:(创建模式同上?,一行解决)

####两种构建方式: # 1.循环模式: {变量(加工后的变量) for 变量 in iterable} # 2.筛选模式: {变量(加工后的变量) for 变量 in iterable if 条件} #集合推导式 print({i for i in range(101)})

八丶内置函数

什么是内置函数:

​ 由python解释器提供的一些特别的方法,目的提高开发效率

内置函数的数量:

​ 目前:内置函数 68种

?看代码吧:

# -*- coding: utf-8 -*- # Author : Ds #eval() 剥去字符串外衣 执行代码 s1='1+3' ret=eval(s1) #去除两端字符,数字相加得到结果 print(ret) #exce() 也是执行代码流, s3=''' for i in range(10): print(i) ''' exec(s3) # 执行for循环 ##建议?: 不要不轻易使用这个两个内置函数. 都是会将代码执行, #假如给了一个字符串的病毒,使用这两个方法任意执行.你的电脑都会中毒 #hash() 得到一个哈希值 print(hash(123)) # 数字的哈希值还是数字 print(hash('abc')) print(hash('abcdkjahfduai')) #help()查看方法, print(help(str.upper())) #callable() 判断是不是一个可调用的对象 # 如果返回 True,object 仍然可能调用失败;但如果返回 False,调用对象 object 绝对不会成功。 def abc(): pass a=123 b='123' print(callable(abc),dir(abc)) # '__call__' print(callable(a)) print(callable(b)) #bin() oct() hex() print(bin(100)) # 将十进制转化成二进制。 逢2进一 print(oct(10)) # 将十进制转化成八进制字符串并返回。 逢8进一 print(hex(17)) # 将十进制转化成十六进制字符串并返回。 逢16进一 # 二进制 # 只有 0 1 两个数字, 逢2进一 #八进制 # 0 - 7 , 逢8进一 #十六进制 #0 - 9 , a-f表示 10 -15 逢16进一 #divmod() 计算除数与被除数的结果,返回一个包含商和余数的元组(a // b, a % b) 分页用到 print(divmod(10, 3)) #round()保留小数位 四舍五入 print(round(3.123)) # pow() x**y x的y次幂 print(pow(2,3)) #ord() 输入字符寻找其在unicode的位置。 print(ord('a')) print(ord('中')) # chr() 输入位置数字找出其对应的字符 print(chr(98)) # print(chr(20104)) # 予 #repr() 原形毕露 保留字符串格式 print('不打广告') print(repr('不打广告')) msg = '我叫%r' %('不打广告') print(msg) #all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE #any() 函数用于判断给定的可迭代参数 iterable 是否全部为 False, # 0,'',[],{},set(),(),None 都是False l1 = [1, 'fgdsa', [], {1: 2}] l2 = [0, '', [], {}] print(all(l1)) # 判断可迭代对象元素全部都为True,返回True print(any(l2)) # 判断可迭代对象元素只要有一个True返回True

九丶匿名函数

定义:

​ 没有名字的函数 ,lambda表达式 ,匿名函数只能构建简单的函数 ,

#普通模式, 定义函数 def func(a,b): return a+b #匿名函数构建 #格式---> lambda关键字 传参 : 返回值 func2=lambda x,y:x+y print(func2(1,2)) # 写匿名函数:接收一个可切片的数据,返回索引为 0与2的对应的元素(元组形式)。 #匿名函数最常用的就是与内置函数结合使用 #1. func3=lambda argv : tuple(argv[0:3:2]) print(func3([1,2,3,4])) #2. func3=lambda x : (x[0],x[2]) print(func3('你好啊的')) #3. func4=lambda x,y : x if x>y else y print(func4(1,2)) #4. func4=lambda *args : max(args) print(func4(1,2,3,4,5))

转载于:https://www.cnblogs.com/dengl/p/11061726.html

相关资源:3.29 python函数2(生成器&列表表达式&生成器表达式&匿名函数&闭包&装饰器) 学习笔记
最新回复(0)