python自己写一个迭代器_python笔记之迭代器和生成器

生成器

生成器函数 —— 本质上就是我们自己写得函数

defgenerator():print(1)return 'a'ret=generator()print(ret)

生成器表达式

g = (i for i in range(10))print(g)for i ing:print(i)

生成器表达式

只要含有yield关键字的函数都是生成器函数yield不能和return共用且需要写在函数内

defgenerator():print(1)yield 'a'

生成器函数 : 执行之后会得到一个生成器作为返回值

ret =generator()print(ret)print(ret.__next__())defgenerator():print(1)yield 'a'

print(2)yield 'b'

yield 'c'g=generator()for i ing:print(i)

ret= g.__next__()print(ret)

ret= g.__next__()print(ret)

ret= g.__next__()print(ret)

生成器函数一

defwahaha():for i in range(2000000):yield '娃哈哈%s'%i

g=wahaha()

g1=wahaha()print(g.__next__())print(g1.__next__())

g=wahaha()

count=0for i ing:

count+=1

print(i)if count > 50:break

#print('*',g.__next__())

for i ing:

count+=1

print(i)if count > 100:break

生成器函数二

生成器函数

defgenerator():print(123)

content= yield 1

print('=======', content)print(456)

arg= yield 2

''''''

yieldg=generator()

ret= g.__next__()print('*', ret)

ret= g.send('hello') #send的效果和next一样

print('*', ret)

生成器函数三

send方法

send 获取下一个值的效果和next基本一致

只是在获取下一个值的时候,给上一yield的位置传递一个数据

使用send的注意事项

第一次使用生成器的时候 是用next获取下一个值

最后一个yield不能接受外部的值

获取移动平均值

def wrapper(func): #在调用被装饰生成器函数的时候首先用next激活生成器

def inner(*args, kwargs):

ret= func(*args, kwargs)

next(ret)returnretreturninner

@wrapperdefaverage():

sum=0

count=0

avg=0whileTrue:

num= yieldavg

sum+= num #10

count += 1 #1

avg = sum /count

avg_g=average()print(avg_g.send(10))print(avg_g.send(20))print(avg_g.send(30))

获取移动平均值

生成器小练习

处理文件,用户指定要查找的文件和内容,将文件中包含要查找内容的每一行都输出到屏幕

defcheck_file(filename, aim):

with open(filename, mode='r', encoding='utf-8') as f: #句柄 : handler,文件操作符,文件句柄

for i inf.readlines():if aim ini:yieldi

g= check_file('test.py', 'def')for i ing:print(i.strip())

写生成器,从文件中读取内容,在每一次读取到的内容之前加上‘*’之后再返回给用户

defcheck_file(filename):

with open(filename, mode='r', encoding='utf-8') as f: #句柄 : handler,文件操作符,文件句柄

for i inf.readlines():yield '*' +i

g= check_file('test.py')for i ing:print(i.strip())

迭代器

迭代

迭代:可以将某个数据集内的数据“一个挨着一个的取出来”,就叫做迭代。

字符串、列表、元组、字典、集合都可迭代对象

可迭代协议:可以被迭代要满足的要求就叫做可迭代协议。可迭代协议的定义非常简单,就是内部实现了__iter__方法

迭代器:内部含有__next__和__iter__方法的就是迭代器

可迭代的.__iter__()方法就可以得到一个迭代器

迭代器中的__next__()方法可以一个一个的获取值

for只有 是可迭代对象的时候 才能用for当我们遇到一个新的变量,不确定能不能for循环的时候,就判断它是否可迭代

l = ["12", '120', '119', '112', '10086', '10000']

iterator= l.__iter__()print(iterator)print(iterator.__next__())

#只要是能被for循环的数据类型 就一定拥有__iter__方法print([].__iter__())

# 一个列表执行了__iter__()之后的返回值就是一个迭代器print(dir([]))print(dir([].__iter__()))print(set(dir([].__iter__())) -set(dir([])))print([1,'a','bbb'].__iter__().__length_hint__()) #元素个数

l = [1,2,3]

iterator= l.__iter__()print(iterator.__next__())print(iterator.__next__())print(iterator.__next__())print(iterator.__next__())

迭代器的好处

从容器类型中一个一个的取值,会把所有的值都取到。

节省内存空间

迭代器并不会在内存中再占用一大块内存,

而是随着循环 每次生成一个

每次next每次给我一个

迭代器和生成器

迭代器

双下方法 : 很少直接调用的方法。一般情况下,是通过其他语法触发的

可迭代的 —— 可迭代协议 含有__iter__的方法('__iter__' in dir(数据))

可迭代的一定可以被for循环

迭代器协议: 含有__iter__和__next__方法

迭代器一定可迭代,可迭代的通过调用iter()方法就能得到一个迭代器

迭代器的特点:

方便逐个取值,一个迭代器只能取一次。

节省内存空间

生成器

生成器的本质就是迭代器

生成器的表现形式

生成器函数

生成器表达式

生成器函数:

含有yield关键字的函数就是生成器函数

特点:

调用函数的之后函数不执行,返回一个生成器

每次调用next方法的时候会取到一个值,遇见yield就停止

直到取完最后一个,在执行next会报错

取值:

for :如果没有break会一直取直到取完

next :每次只取一个

send :不能用在第一个,取下一个值的时候给上个位置传一个新的值

数据类型强制转换 :会一次性把所有数据都读到内存里

生成器表达式

(条件成立想放在生成器中的值 for i in 可迭代的 if 条件)

写生成器实现:有一个文件,从文件里分段读取内容readlineread(10)在读出来的内容前面加上一个'*',再返回给调用者

defgenerator():for i in range(20):yield '哇哈哈%s' %i

g= generator() #调用生成器函数得到一个生成器

print(list(g))

ret= g.__next__() #每一次执行g.__next__就是从生成器中取值,预示着生成器函数中的代码继续执行

print(ret)

你可能感兴趣的:(python自己写一个迭代器)