python开发函数进阶:可迭代的&迭代器&生成器

时间:2023-03-09 19:07:24
python开发函数进阶:可迭代的&迭代器&生成器

一,可迭代的&可迭代对象

1.一个一个的取值就是可迭代的   iterable
#str list tuple set dict
#可迭代的 ——对应的标志 __iter__

2.判断一个变量是不是一个可迭代的

# print('__iter__' in dir(list))
# print('__iter__' in dir([1,2,3]))

3.可迭代协议——凡是可迭代的内部都有一个__iter__方法

二,迭代器

1.将可迭代的转化成迭代器

 #!/usr/bin/env python
#_*_coding:utf-8_*_ # iterator #迭代器
# iterator iterable#可迭代对象
l = [1,2,3,4,5]
for i in l:
print(i)
print(iter(l)) #内置函数 iter == l._iter_()
l.__iter__()
l_iterator = iter(l)
print(set(dir(l_iterator))-set(dir(l)))
print(next(l_iterator)) #迭代器就要通过next方法取值

2.迭代器小结

#迭代器里既有iter方法,又有next方法 ——迭代器协议
#通过iter(o)得到的结果就是一个迭代器,
#o是一个可迭代的

#迭代器 大部分都是在python的内部去使用的,我们直接拿来用就行了
#迭代器:内置__iter__和__next__方法

 #!/usr/bin/env python
#_*_coding:utf-8_*_ l = [1,2,3,4,5]
l_iterator = iter(l)
print(l_iterator.__next__())
print(l_iterator.__next__())
print(l_iterator.__next__())
print(l_iterator.__next__())
print(l_iterator.__next__())
next(l_iterator) #==l_iterator.__next__()
# while True: 自己写相当于for循环
# try:
# print(next(l_iterator))
# except StopIteration:
# break

3.判断是否是迭代器 和 可迭代对象的简便方法

 #!/usr/bin/env python
#_*_coding:utf-8_*_ from collections import Iterable
from collections import Iterator
# s = 'abc'
# print(isinstance(s,Iterable)) s 是不是一个可迭代对象
# print(isinstance(s,Iterator)) s 是不是一个迭代对象
# print(isinstance(iter(s),Iterator))

4.可迭代的和迭代器

#不管是一个迭代器还是一个可迭代对象,都可以使用for循环遍历
#迭代器出现的原因 帮你节省内存

三,生成器

#生成器函数
#生成器的本质就是迭代器

 #!/usr/bin/env python
#_*_coding:utf-8_*_ def func():
print('aaaa')
a = 1
yield a #返回第一个值
print('bbbb')
yield 12 #返回第二个值
#错误取值,相当于三个新的生成器
# print(next(func() )) #取第一个值
# print(next(func() )) #取第一个值
# print(next(func() )) #取第一个值
#正确取值,都是同一个生成器
# ret = func() #拿到一个生成器
# # print(ret)
# print(next(ret)) #取第一个值
# print(next(ret)) #取第二个值
# print(next(ret)) #取第三个值 会报错 因为没有第三个值

3,1 生成器做衣服实例

 #/usr/bin/env python
#_*_coding:utf-8_*_ def make_cloth():
for i in range(2000000):
yield "第%s件衣服"%i
# szq = make_cloth()
# print(next(szq))
# print(next(szq))
#
# print(next(szq))
# for i in range(50):
# print(next(szq))

3.2 监听文件实例

 #!/usr/bin/env python
#_*_codingLutf-8_*_ #监听文件 tail -f
import time
def tail(filename):
with open(filename) as f:
f.seek(0, 2) #从文件末尾算起
while True:
line = f.readline() # 读取文件中新的文本行
if not line:
time.sleep(0.1)
continue
yield line # for line in tail('tmp_file'):
# print(line,end = '')

3.3 计算移动平均值

 #!/usr/bin/env python
#_*_coding:utf-8_*_ #7日平均年化收益
def averager():
total = 0
day = 0
avrage = 0
while True:
day_num = yield avrage #return avrage
total += day_num
day += 1
avrage = total/day # avg = averager()
# num = next(avg) #激活生成器 avg.send(),什么都不send和next效果一样
# print(avg.send(10)) #传值 next
# print(avg.send(20))

3.4 带装饰器的生成器

 #!/usr/bin/env python
#_*_codingLutf-8_*_ def wrap(func):
def inner(*args,**kwargs):
g = func(*args,**kwargs)
next(g)
return g
return inner @wrap
def averager():
total = 0
day = 0
avrage = 0
while True:
day_num = yield avrage #return avrage
total += day_num
day += 1
avrage = total/day # g = averager()
# print(g.send(10))
# print(g.send(20))