生成器初识,推导式,
1.生成器初始
- 生成器本身就是迭代器.python社区生成器与迭代器是一种,生成器与迭代器的唯一区别 :生成器是我们自己用Python代码构建的
2.生成器的产生方式
-
生成器函数
-
ret =next()时,打印ret时一直打印的是ret通过next接收到的yield的值,只执行一次next, ret = (),打印next(ret)时,打印出的是next这个操作,相当于进行很多次的next
-
注意:等号是赋值,等号右边的函数操作不再执行
-
之前接触的函数:
# def func(): # print(111) # return 2 # ret = func() # print(ret) # 执行此函数,遇到return结束函数。 # 将数字2返回给ret。
生成器函数: 只要函数中出现了yield那么他就不是函数,它是生成器函数
def func(): # print(111) # print(111) # print(111) # print(111) # print(111) # print(111) yield 2,4,5 yield 3 yield 4 yield 5 ret = func() # 生成器对象 # print(ret) # <generator object func at 0x0000000001E10F68> ''' # 类比 l1 = [2,] [2,3,4,5] obj = iter(l1) ''' # 只要函数中出现了yield那么他就不是函数,它是生成器函数。 # 一个next对应一个yield. # print(next(ret)) # print(next(ret)) # print(next(ret)) # print(next(ret)) # print(next(ret)) # print(next(ret))
-
-
生成器表达方式
-
python给你提供一些内置函数,返回一个生成器
3.yiled 与 return的区别
- return 结束函数,给函数的执行者返回值(多个值通过元组的形式返回)
- yield 不结束函数,对应着给next 返回值(多个值通过元组的形式返回
4.send(了解)
5.生成器的举例
-
ret =next()时,打印ret时一直打印的是ret通过next接收到的yield的值,只执行一次next, ret = (),打印next(ret)时,打印出的是next这个操作,相当于进行很多次的next
-
注意:等号是赋值,等号右边的函数操作不再执行
-
# def eat_baozi(): # list1 = [] # for i in range(1,2001): # list1.append(f'{i}号包子') # return list1 # # print(eat_baozi()) def eat_baozi_gen(): for i in range(1,2001): # print(11) yield f'{i}号包子' ''' # ret1 = eat_baozi_gen() # ret2 = eat_baozi_gen() # # print(ret1) # # print(ret2) # print(next(ret1)) # print(next(ret1)) # print(next(ret1)) # # print(next(ret2)) # print(next(ret2)) # print(next(ret2)) # print(next(ret)) # print(next(ret)) ''' # ret = eat_baozi_gen() # # for i in range(200): # print(next(ret)) # # for i in range(200): # print(next(ret))
6.yiled与yiled from
-
# yield from # def func(): # l1 = [1, 2, 3] # yield l1 # ret = func() # print(next(ret)) # print(next(ret)) # print(next(ret)) # 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循环)
7 列表推导式,生成器表达式(字典推导式,集合推导式)
-
列表推导式 : 一行代码构建一个有规律比较复杂的列表
- 列表推导式:一行代码构建一个有规律比较复杂的列表。
- 列表推导式与之前写法对比
# l1 = [1,2,3......100] # 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)])
-
筛选模式:
# 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])
-
列表推导式的优缺点:
# 列表推导式的优缺点: # 优点: # 1, 简单,快捷,装b。 # 缺点: # 2. 可读性不高,不好排错。 # 慎用,不要入迷。
-
生成器表达式:
与列表推导式几乎一模一样。
循环模式,筛选模式。
# obj = (i for i in range(1, 11)) # # print(obj) # # print(next(obj)) # # print(next(obj)) # # print(next(obj)) # # print(next(obj)) # # print(next(obj)) # # print(next(obj)) # # print(next(obj)) # # print(next(obj)) # # print(next(obj)) # # print(next(obj)) # # print(next(obj))
- 如何触发生成器(迭代器)取值?
# # 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)})