一、生成器
1、生成器的本质就是迭代器,一个一个的创建对象
2、创建生成器的方式
1、生成器函数
2、通过生成器表达式来获取生成器
3、通过数据的转化也可以获取生成器
二、生成器函数
生成器函数中包含yield,返回数据和return差不多
不同点:
return 会立即结束这个函数的执行
yield可以分段的执行一个函数
def func(): print(\'今天天气如何?\') yield \'晴天\' print(\'明天天气如何?\') yield \'阴天\' print(\'后天天气怎么样\') yield \'谁知道呢\' ret = func() # 执行函数,此时没有运行函数,此时拿到的是一个生成器 print(\'返回值是:\',ret) # 返回值是: <generator func at 0x000001AA87C45BA0> print(ret.__next__()) # 第一次执行__next__的时候,函数才开始执行 print(ret.__next__()) # 执行下一个yield print(ret.__next__()) # StopInteration
生成器函数能向下执行到两个条件:
1、 __next__(),执行到下一个yield
2、send(),执行到下一个yield,给上一个yield位置传值
所有的生成器都是迭代器都可以使用for循环
都可以shiyonglist()函数来获取到生成器内的所有元素
例子
第一种 # 买100件衣服 def buy(): st = [] for i in range(1,101): lst.append(\"衣服%s\"% i) return lst lst = buy() print(lst) 第二种 用生成器 def buy(): for i in range(101): yield \"衣服%s\"%i gen = buy() #生成器或者迭代器的好处:节省内存 print(gen.__next__()) # 需要一件拿一件 print(gen.__next__()) print(gen.__next__()) for yifu in gen: # 迭代器.__next__() print(yifu) lst = list(gen) # 内部使用的是for 循环 ->__next__() print(lst)
send() 执行到下一个yield,给上一个yield位置传值
def func(): print(\'你喜欢什么水果\') a = yield \"芒果\" print(\"a\", a) b = yield \"苹果\" print(\"b\", b) c = yield \"柚子\" print(\"c\",c) gen = func() print(gen.__next__()) print(gen.__next__()) print(gen.__next__()) # 你喜欢什么水果 # 芒果 # a None # 苹果 # b None # 柚子 结论:执行函数时,a,b,c 都返回None gen = func() print(gen.__next__()) # 第一个位置用send没有任何意义 print(gen.send(\"篮球\")) # 给上一个yield位置传值 print(gen.send(\"足球\")) # 你喜欢什么水果 # 芒果 # a 篮球 # 苹果 # b 足球 # 柚子
生成器中记录的是代码而不是函数的运作
def func():
print(\'哈哈\')
yield \'\'大风
gen = func() # 创建生成器,此时运行会把生成器函数中的代码记录在内存
当执行到__next__(),运行此空间中的代码,运行到yield结束
优点:节省内存,生成器本身就是代码,几乎不占内存
特点:惰性机制,只能向前,不能反复
三、各种推导式
1、列表推导式 [结果 for循环 if判断]
# 生成列表.类表中装的数据是 1-100之间所有的偶数的平方 lst =[i ** 2 for i in range(1,101) if i %2 == 0] print(lst)
# # 寻找名字中带有两个e的人的名字 names = [[\'Tom\', \'Billy\', \'Jefferson\', \'Andrew\', \'Wesley\', \'Steven\',\'Joe\'], [\'Alice\', \'Jill\', \'Ana\', \'Wendy\', \'Jennifer\', \'Sherry\', \'Eva\']] lst = [name for first in names for name in first if name.count(\"e\") == 2] print(lst)
2、字典推导式{结果(k,v)for 循环 if判断}
# 把字典的key和value互换, 生成新字典 dic = {\"主食\": \"炒面\", \"副食\": \"小拌菜\", \"汤\":\"疙瘩汤\"} dic1 = {v:k for k,v in dic.items() } print(dic1)
3、集合推导式 {结果(k) for 循环 if 判断}
没有元组推导式
四、生成器表达式
(结果 for 循环 if)
g = (i for i in range(10)) # 生成器表达式 print(g) # <generator <genexpr> at 0x000001F7769F5938>
yield from # 可以把一个可迭代对象分别进行yield返回
def func(): lst = [\"水果%s\"% i for i in range(10)] yield from lst gen = func() ret = gen.__next__() print(ret) ret = gen.__next__() print(ret) # 水果0 # 水果1
添加 写代码的注意事项
def func(name,info): \'\'\' 函数功能 :param name: 参数name :param info: 参数 info :return: 返回什么内容 :creator:创建者 :author :作者 :date:时间 \'\'\' a = func print(\"***\") print(\"***\") print(\"***\") print(\"***\") ... a(\'\',\'\') # 中间的代码内容过长,查找a的名字 print(a.__name__) # 看到函数的真实的名字(相对) print(a.__doc__) # 函数的功能
面试相关的有坑的题
深坑,需要值的时候才去拿值
def func(): print(111) yield 222 g = func() # 创建生成器 g1 = (i for i in g) # 生成器表达式,生成器g1,g1的数据来源于g g2 = (i for i in g1) # 生成器表达式 生成器g2,g2的数据来源于g1 print(list(g)) # 获取g中的数据,这时func()才会被执行,打印111,获取222,g完毕 print(list(g1)) # 获取g1的数据,g1的数据来源时g,但是g已经被取完了,所有g1没有数据 print(list(g2)) # 与g1同理
# 如下代码打印的结果分别是什么 def extendList(val,list=[]): # 多次调用使用同一个列表 print(id(list)) list.append(val) # 把元素添加到列表,然后返回列表 return list list1 = extendList(10) list2 = extendList(123,[]) list3 = extendList(\"a\") print(\"list1 = %s\"%list1) print(\"list2 = %s\"%list2) print(\"list3 = %s\"%list3) # list1 = [10, \'a\'] # list2 = [123] # list3 = [10, \'a\']
继续阅读与本文标签相同的文章
上一篇 :
17年大盘点:区块链领域常见术语详析
-
在Win上做Python开发?当然是用官方的MS Terminal和VS Code了
2026-05-19栏目: 教程
-
受用一生的高效 PyCharm 使用技巧(四)
2026-05-19栏目: 教程
-
Springboot 之创建自定义starter
2026-05-19栏目: 教程
-
黑客们会用到哪些Python技术?
2026-05-19栏目: 教程
-
菜鸟如何在阿里云快速建站(pc站+手机站+公众号+小程序)
2026-05-19栏目: 教程
