day 关于生成器的函数
def average():
count=0
toatal=0
average=0
while True:
value=yield average
toatal+=value
count+=1
average=toatal/count
g=average()
print(g.__next__()) #激活了生成器,调用函数后 从头开始到 返回average 返回yield后面的average,为0
print(g.send(10)) #把10传递给yield前的value,继续执行后面的代码,value = 10 total= 10+0 count =1+0 average= 10/1 = 10
print(g.send(20)) #把20传递给yield前的value,继续执行后面的代码,value = 20 total= 10+20 count =1+1 average= 30/2 =15
print(g.send(30)) #把30传递给yield前的value,继续执行后面的代码,value = 30 total= 30+30 count =1+1+1 average= 90/3 =30
print(g.send(40))
print(g.send(50))
一、迭代器(dir()可以查函数具有什么键的功能)
1、可迭代的——iterable(字符串、列表、元组、字典、集合都可以被for循环,说明他们都是可迭代的。)
可以被for循环的都是可迭代的,要想可迭代,内部必须有一个__iter__方法。
(1)判断是否可迭代的方法:
from collections import Iterable
print(isinstance('aaa',Iterable) #输出结果:True
print(isinstance(123,Iterable) #输出结果:False
print(isinstance([1,2,3],Iterable) #输出结果:True
(2)可迭代协议
包含‘__iter__'方法的数据类型就是可迭代的。输出数据类型所有方法的方式如下:
#实例:求出两个不同数据类型的方法的不同
difference=set(dir([1,2,3]))-set(dir(123)) #dir()方法以列表形式列出数据的所有的方法
print(diffenrence)
2、迭代器——iterator
(1)判断迭代器的方法(迭代器 : __iter__ 和__next__)
from collection import Iterator
iterator_lst=[1,2,3].__iter__()
print(isinstance(itertor_lst,Iterator) #输出结果为:True
print(isinstance([1,2,3],Iterator) #输出结果为:False
print('__next__' in dir([1,2,3,4])) # False
(2)迭代器协议
迭代器中有'__next__'和'__iter__'方法
(3)常见迭代器
a.先天的:文件句柄;b后天的:从可迭代对象转变,格式为:“可迭代对象.__iter__()”
(4)迭代器取值
lst_iterator=[1,2,3].__iter__() 先有iter
print(lst_iterator.__next__()) 才能取值 #输出结果为:1
print(lst_iterator.__next__()) #输出结果为:2
print(lst_iterator.__next__()) #输出结果为:3
#超过迭代器中的内容就会报错:stopIterator
(5)优点(迭代器是个好东西)
3、二者的区别
(1)可迭代对象包含迭代器;(2)迭代器=可迭代对象.__iter__();(3)可以对可迭代对象和迭代器进行循环
二、生成器
1、定义:生成器就是迭代器,生成器是我们自己写出来的
2、生成器函数:带有关键字yield/yield from的函数就称为生成器函数
(1)生成器函数在执行时候只返回一个生成器,不执行生成器函数中的内容
(2)从生成器中取值
a.生成器.__next__():生成器函数中有几个yield,就可以取几次
def generator():
print(123)
yield 'aaa'
print(456)
yield 'bbb'
g=generator()
print(g.__next__()) # 123 aaa
print(g.__next__()) # 456 bbb
def list():
print(123)
yield 'aaa'
print(456)
yield 'bbb'
print(list().__next__()) # 123 aaa
print(list().__next__()) # 123 aaa
注意:前者为创建一个生成器,后者为每次重新创建一个生成器
b、for 循环取值
def func():
print(123)
yield 'aaa'
print(456)
yield 'bbb'
g=func()
for i in g:
print(i)
123
aaa
456
bbb
l = [1,2,3,4,5]
l_iter = l.__iter__() 定义
while True:
try:
print(l_iter.__next__())
except StopIteration: # 异常处理机制
break
实例、
def cloth():
for i in range(10000):
yield '衣服%s'%i g = cloth()
for i in range(50):
print(g.__next__()) for i in range(50):
print(g.__next__())
list(生成器函数) 返回一个列表,里面装着生成器中的所有内容
def generator():
yield 'aaa'
yield 'bbb'
g=generator()
print(list(g)) # [aaa,bbb]
实例
1、监听器例子
监听器
def tail():
f = open('文件','r',encoding='utf-8')
f.seek(0,2) # 光标移至最后
while True:
line = f.readline()
if line:
yield line
import time
time.sleep(0.1)
g = tail()
for i in g:
print(i.strip())
生成器监听文件输入的例子
2、计算移动平均值
def averger():
total = 0.0
count = 0
average = None
while True:
term = yield average
total += term
count += 1
average = total/count g_avg = averger()
next(g_avg)
print(g_avg.send(10))
print(g_avg.send(100))
print(g_avg.send(20))
print(g_avg.send(30))
三、重要会
def g_func():
print('aaaaa') # aaaaa
yield 1 # 返回值 每次只占用一次内存,用完就没了
print('bbbbb') #bbbbb
yield 2 # 返回值
yield 3 # 返回值
# return [1,2,3] #直接return 是列表,当列表数大的时候会比较占用内存
# for i in range(20000): #当数量较大时,生成器函数可以这样写、
# yield i
g = g_func()
# for i in g:
# print(i) print(g.__next__())
print(g.__next__())
print(g.__next__())
def cloth():
for i in range(10000):
yield '衣服%s'%i g = cloth()
for i in range(50):
print(g.__next__()) for i in range(50):
print(g.__next__())
一、生成器中的send用法
send可以把一个值作为信号量传递到生成器函数中,然后和__next__方法一样获取生成器中的值;在生成器执行伊始,只能先使用__next__;二者都是终于yield,而send需要始于一个未被返还的yield处,否则传递的数值将无法被接收。
1、求重复累加平均实例
def average():
count=0
toatal=0
average=0
while True:
value=yield average
toatal+=value
count+=1
average=toatal/count
g=average()
print(g.__next__()) #激活了生成器,返回yield后面的average,为0
print(g.send(10)) #把10传递给yield前的value,继续执行后面的代码,终于yield后面的average,返回10
print(g.send(20)) #把20传递给yield前的value,继续执行后面的代码,终于yield后面的average,返回15
print(g.send(30)) #..........
print(g.send(40))
print(g.send(50))
2、用send传值失败实例
def func():
print(1)
yield 2
print(3)
value = yield 4
print(5)
yield value g = func()
print(g.__next__()) #打印出1和返回2,然后在第一个yield处停止等待
print(g.send(88)) #由于第一个yield处没有未被返回的值,故send传值失败,打印出3和返回4,在第二个yield处停止等待
print(g.__next__()) #value无值传入,打印出5后在第3个yield处返回none
3、用next激活生成器计算累加平均值
def init(func): #在调用被装饰生成器函数的时候首先用next激活生成器
def inner(*args,**kwargs):
g=func(*args,**kwargs)
next(g)
return g
return inner
@init
def average():
mount=0
total=0
average=0
while True:
value=yield average
total+=value
average=total/mount
g_avg=average()
# next(g_avg) 在装饰器中执行了next方法
print(g_avg.send(10))
print(g_avg.send(20))
print(g_avg.send(30))
二、列表表达式和生成器表达式
1、列表表达式
简化代码,返回的必须是一个列表
#普通代码
result=[]
for i in [1,2,3]
result.append[i*i]
print(result) #列表表达式
print([i*i for i in [1,2,3]])
(1)30内能被3整除的数的实例
print([i for i in range(1,31) if i%3==0])
(2)找到嵌套列表中有两个‘e’的名字
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
print([for list in names for name in list if name.count('e')==2])
2、生成器表达式
把列表解析的[]换成()得到的就是生成器表达式;列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存
laomuji=('鸡蛋%s' %i for i in range(10)) #生成器表达式
print(laomuji) #返回生成器地址<generator object <genexpr> at 0x000001E17AF23BA0>
print(next(laomuji)) #输出结果为:鸡蛋0
print(laomuji.__next__()) #输出结果为:鸡蛋1
print(next(laomuji)) #输出结果为:鸡蛋2
#next(laomuji)等价于laomuji.__next__()
3、字典推导式
#将字典键与值对调
mcase = {'a': 10, 'b': 34}
print({mcase[k]:k for k in mcase})
4、集合推导式
自带去重功能,将列表解析式的[]换成{}得到集合推导式
print({i*i for i in [1,-1,2]}) #结果为{1,4}
1.把列表解析的[]换成()得到的就是生成器表达式
2.列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存
3.Python不但使用迭代器协议,让for循环变得更加通用。大部分内置函数,也是使用迭代器协议访问对象的。例如, sum函数是Python的内置函数,该函数使用迭代器协议访问对象,而生成器实现了迭代器协议,所以,我们可以直接这样计算一系列值的和:
sum(x ** 2 for x in range(4))
而不用多此一举的先构造一个列表:
sum([x ** 2 for x in range(4)])
生成器面试题
def demo():
for i in range(4):
yield i g=demo() # 生成器 g1=(i for i in g) #生成器
g2=(i for i in g1) #g2 生成器 # print(list(g1)) #[0,1,2,3]
print(list(g2))
def add(n,i):
return n+i def tes():
for i in range(4):
yield i g=tes()
for n in [1,5,10]:
g=(add(n,i) for i in g)
n=1
g=(add(n,i) for i in tes()) #---> g=(add(n,i) for i in g) 生成器,没要,不会给值 -->tes() = g
n = 5
g=(add(n,i) for i in (add(n,i) for i in tes()))
n = 10
g=(add(n,i) for i in (add(n,i) for i in (add(n,i) for i in tes())))
# g=(30,31,32,33)
print(list(g))
day 关于生成器的函数的更多相关文章
- python生成器,函数,数组
1.什么是生成器用一个比喻来形容,工厂中生产保龄球的流水线,机器每次只生产一个保龄球,下次继续生产下一个,直到停止(原料不足,停止供电等条件)为止.机器就是我们的生成器. 2.使用示例在python中 ...
- Python语言的循环语句、迭代器与生成器、函数学习
while循环语句 无限循环 我们可以通过设置条件表达式永远不为false来实现无限循环,实例如下: for语句 Python for循环可以遍历任何序列的项目,如一个列表或者一个字符串 Python ...
- 生成器执行函数co 源码解读
本文所选内容均来自[co模块源码] /** * slice() reference. */ var slice = Array.prototype.slice; module.exports = co ...
- python函数(5):迭代器和生成器
迭代器和生成器是函数中的一大重点,务必掌握,何为迭代?何为迭代器? 预习: 处理文件,用户指定要查找的文件和内容,将文件中包含要查找内容的每一行都输出到屏幕 一.迭代器 for i in 50: pr ...
- Python_Mix*生成器,生成器函数,推导式,生成器表达式
生成器: 生成器的本质就是迭代器 生成器一般由生成器函数或者生成器表达式来创建,其实就是手写的迭代器 def func(): print('abc') yield 222 #由于函数中有了yield ...
- day14,函数的使用方法:生成器表达式,生成器函数
生成器表达式: #列表推导式 # y = [1,2,3,4,5,6,7,8] # x = [1,4,9,16,25,36,49,64] # x = [] # for i in y: # x.appen ...
- 解释生成器(generator)于函数的不同,并实现和使用简单generator?
生成器和函数的主要区别在于函数return avalue,生成器yield a value,同事标记或记忆point of the yield 以便在下次调用时从标记点恢复执行,yield使用函数 ...
- Python之生成器及内置函数篇4
一.可迭代对象 #1.什么是迭代?:迭代是一个重复的过程,并且每次重复都是基于上一次的结果而来 #2.可迭代的对象:在python中,但凡内置有__iter__方法的对象,都是可迭代的对象 #3.迭代 ...
- Python函数系列-迭代器,生成器
一 迭代器 一 迭代的概念 #迭代器即迭代的工具,那什么是迭代呢?#迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单纯地重复,因而不 ...
随机推荐
- Windows 上安装 Scala
在安装 Scala 之前需要先安装 Java 环境,具体安装的详细方法就不在这里描述了. 您可以自行搜索我们网站中的内容获得其他网站的帮助来获得如何安装 Java 环境的方法. 接下来,我们可以从 S ...
- node初学者笔记
helloworld 编辑一个js文件——在该文件所属目录打开命令行cmd——输入'node -v可查看版本——输入'node 00-hellowolrd.js(你的js名字)' 或者直接在文件所属 ...
- pytorch学习记录
1.pytorch中的torch.split只能将tensor分割为相等的几分,如果需要特定的需求将tensor分割开,可以用torch.index_select.使用的时候,先生成index索引,示 ...
- Wannafly挑战赛23B游戏
https://www.nowcoder.com/acm/contest/161/B 题意:两个人van游戏,n堆石子,每次只能取这堆石子数目的因子个数,没得取的人输,问第一个人的必胜策略有多少种 题 ...
- spring boot 2.0(一)权威发布spring boot2.0
Spring Boot2.0.0.RELEASE正式发布,在发布Spring Boot2.0的时候还出现一个小插曲,将Spring Boot2.0同步到Maven仓库的时候出现了错误,然后Spring ...
- js事件流 事件捕获 及时间冒泡详解
Javascript与HTML之间的交互是通过事件实现. 一.事件流 事件,是文档或浏览器窗口中发生的一些特定的交互瞬间.事件流,描述的是页面中接受事件的顺序.IE9,chrome,Firefox,O ...
- atoi函数原型
一.atoi()函数的功能: 1.定义: 将字符串转换成整型数,跳过前面的空格字符,直到遇上数字或正负号才开始做转换,而再遇到非数字或字符串时('\0')结束转化,并将结果返回(返回转换后的整型数). ...
- git相关知识(github,idea等的配置)
本地git提交文件到github上: 1.在github上创建项目 2.使用git clone https://github.com/xxxxxxx/xxxxx.git克隆到本地 3.编辑项目 4.g ...
- 使用python操作hdfs,并grep想要的数据
代码如下: import subprocess for day in range(24, 30): for h in range(0, 24): filename = "tls-metada ...
- png文件格式详解,获取文件的修改时间,创作时间
http://dev.gameres.com/Program/Visual/Other/PNGFormat.htmhttp://www.360doc.com/content/11/0428/12/10 ...