-
生成器初识
生成器本质就是迭代器。python社区中生成器与迭代器是一种概念。生成器与迭代器的唯一区别:迭代器都是Python给你提供的已经写好的工具或者通过数据转化得来的,(比如文件句柄,iter([1,2,3])。生成器是我们自己用python代码构建的工具。
-
生成器构建方式
- 生成器函数。
- 生成器表达式。
- python给你提供的一些内置函数,返回一个生成器。
-
生成器函数。
生成器函数: 只要函数中出现了yield那么他就不是函数,它是生成器函数
def func(): print(111) yield 2,4,5 print(222) yield 3 ret = func() # 生成器对象 print(ret) # <generator object func at 0x0000000001E10F68> # 只要函数中出现了yield那么他就不是函数,它是生成器函数。 # 一个next对应一个yield.next超过yield数量,就会报错,与迭代器一样。 print(next(ret)) print(next(ret))
-
yiled与return的区别
# return 结束函数,给函数的执行者返回值(多个值通过元组的形式返回)。 # yield 不结束函数,对应着给next返回值(多个值通过元组的形式返回)。
-
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置传递值。
-
yiled与yiled from。
# yield from 的作用 def func(): l1 = [1, 2, 3] yield from l1 ''' yield 1 yield 2 yield 3 ''' ret = func() print(next(ret)) print(next(ret)) print(next(ret)) # yield : 对应next给next返回值 # yield from 将一个可迭代对象的每一个元素返回给next # yield from 节省代码,提升效率(代替了for循环)
-
列表推导式,生成器表达式(字典推导式,集合推导式)。
列表推导式:一行代码构建一个有规律比较复杂的列表。
列表推导式与之前写法对比
l1 = [] for i in range(1,101): l1.append(i) print(l1) # 列表推导式 l1 = [i for i in range(1, 101)] print(l1)
两种构建方式:
1.循环模式: [变量(加工后的变量) for 变量 in iterable]
2.筛选模式: [变量(加工后的变量) for 变量 in iterable if 条件]
循环模式:
# 循环模式: # 将10以内所有整数的平方写入列表。 print([i**2 for i in range(1, 11)]) # 100以内所有的偶数写入列表. print([i for i in range(2, 101, 2)]) # 从python1期到python100期写入列表list print([f'python{i}期' for i in range(1, 101)])
筛选模式:
# 1-100里大于49的数 print([i for i in range(1, 101) if i > 49]) # 三十以内可以被三整除的数。 print([i for i in range(1, 31) if i % 3 == 0]) # 过滤掉长度小于3的字符串列表,并将剩下的转换成大写字母 l1 = ['barry', 'fdsaf', 'alex', 'sb', 'ab'] print([i.upper() for i in l1 if len(i) > 3]) # 找到嵌套列表中名字含有两个‘e’的所有名字(有难度) names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']] l1 = [] for i in names: for j in i: if j.count('e') > 1: l1.append(j) print(l1) # 列表推导式 print([j for i in names for j in i if j.count('e') > 1])
列表推导式的优缺点:
列表推导式的优缺点: 优点: 简单,快捷,装b。 缺点: 可读性不高,不好排错。 # 慎用,不要入迷。
生成器表达式:
与列表推导式几乎一模一样。
循环模式,筛选模式。
obj = (i for i in range(1, 11)) # 把中括号换成小括号解释生成器表达式
如何触发生成器(迭代器)取值?
1. next(obj) 2. for 循环 for i in obj: print(i) 3. 数据转化 print(list(obj)) # 生成器表达式:生成器 节省内存。
字典推导式,集合推导式
# 字典推导式,集合推导式: 两种模式: 循环模式,筛选模式 l1 = ['小潘', '怼怼哥','西门大官人', '小泽ml亚'] # {0: '小潘', 1: '怼怼哥', 2: '西门大官人'} dic = {} for index in range(len(l1)): dic[index] = l1[index] print(dic) # 字典推导式 print({i:l1[i] for i in range(len(l1))}) # 集合推导式生成 1~100的集合 print({i for i in range(1, 101)})
-
匿名函数。
# 匿名函数:没有名字的函数 # 匿名函数只能构建简单的函数,一句话函数。 def func(x,y): return x + y print(func(1, 2)) # 3 # 匿名函数构建 func2 = lambda x,y: x + y print(func2(1, 2)) # 3 # 匿名函数最常用的就是与内置函数结合使用。 # 写匿名函数:接收一个可切片的数据,返回索引为 0与2的对应的元素(元组形式)。 func = lambda x: (x[0],x[2]) print(func('太白金星')) # ['太','金'] # 写匿名函数:接收两个int参数,将较大的数据返回。 func1 = lambda x, y: x if x > y else y print(func1(100,2)) # 100 func2 = lambda : 3 print(func2()) # 3
来源:https://www.cnblogs.com/changyifei-8/p/11061386.html