Fork me on GitHub

迭代器

1、什么是迭代器

器=》工具
迭代:是一个重复的过程,但每次重复都是基于上一次的结果而来的

names=["egon",'lqz','yj']

count = 1
while count < len(names):
    print(names[count])
    count+=1
迭代器:就是一种不依赖于索引的取值工具

2、为何要有迭代器

特性:
    1、是一种通用的迭代取值方案
    2、惰性计算,节省内存

3、如何用迭代器

一:引入

dic={'name':'egon','age':'18','gender':'male'}

dic_iterator=dic.__iter__()
print(next(dic_iterator))
print(next(dic_iterator))
print(next(dic_iterator))
print(next(dic_iterator))      StopIteration

while True:
    try:
        print(next(dic_iterator))  #循环取出
    except StopIteration:       #捕捉异常,不会报错
        break

二:可迭代对象与迭代器对象

2.1 内置有__iter__方法的类型称之为:可迭代对象/类型
1.字典dict
2.集合set
3.文件对象(也是迭代器对象)

with open('login.txt','rb') as f:
    print(f.readline())
    print(f.readline())
    print(f.readline())
    f没有经历__iter__的操作即可被迭代

4.字符串str
5.列表list
6.元组tuple

2.2 迭代器对象:内置有__next__方法、内置有__iter__方法

dic={'name':'egon','age':18,'gender':'male'}
dic_iterator1=dic.__iter__()
res=dic_iterator1.__next__()
print(dic_iterator1.__iter__().__iter__() is dic_iterator1)    #True
#迭代器可以再次用内置方法__iter__,结果成为的还是自己
dic_iterator2=dic.__iter__()
print(dic_iterator1 is dic_iterator2)          
#False 两个变量名开辟的内存空间自然不同

三:for循环的工作原理

dic={'name':'egon','age':18,'gender':'male'}
dic_iterator = dic.__iter__()
while True:
    try:
        res = dic_iterator.__next__()
        print(res)
    except StopIteration:
        break
print(dic) #没有改变原函数
for k in dic:
    print(k)

步骤1 dic_iterator = dic.iter() 可迭代对象成为迭代器,然后重新赋值,没有改变原函数

步骤2 k=dic_iterator.next(),执行循环体代码

步骤3 循环往复,直到抛出异常,for循环会帮我们捕捉异常结束循环

dic={'name':'egon','age':18,'gender':'male'}
dic_iterator = dic.__iter__()
for k in dic_iterator:
    print(k)

四:基于同一迭代器的重复取值,效果如何

dic = {'name': 'egon', 'age': 18, 'gender': 'male'}                                     
dic_iterator = dic.__iter__()                                                           
while True:                                                                             
    try:                                                                                
        res = dic_iterator.__next__()                                                   
        print(res)                                                                      
    except StopIteration:                                                               
        break                       #已经把值全部取完了                                          

dic_iterator = dic.__iter__()       #同理,在中间重新再次赋值一个迭代器就可以再进行迭代                          
while True:                                                                             
    try:                                                                                
        res = dic_iterator.__next__()                                                   
        print(res)                                                                      
    except StopIteration:           #执行到此循环直接第一步就异常被捕捉结束了                               
        break                                                                           

for k in dic:                                                                           
    print(k)                                                                            

for k in dic:                                                                           
    print(k)                                                                            
#每次都会产生新的迭代器进行循环               

自定义迭代器来实现惰性计算,从而达到节省内存的效果

4.什么是生成器

但凡是函数内出现了yield关键字,调用函数将不会执行函数体代码,会得到一个返回值
该返回值就是我们自定义的迭代器,称之为生成器

def func():
    print('hellp1')
    yield 111
    print('hello2')
    yield 222
    print('hello3')
    yield 333

#func()    #func()已经成为了生成器不能产生调用
print(func()) #generator object func at 0x7fcf75fc76d0 生成器
print(func)   #function func at 0x7faf576ba1f0 函数内存地址
a=func().__next__()
print(a)
b=func().__next__()
print(b)
c=func().__next__()
print(c)

5.yield与return

(1):相同点:都可以用来返回值
(2):不同点:
return只能返回一次值,函数就立即结束了
yield能返回多个值,yield可以挂起函数(暂停函数的执行状态,等待下一次的next的调用)

案例

def func():
    res=0
    while True:
        res+=1
        yield res

能循环取出无穷的数,且被取的值是生成器(占用的能存极少),
如果是在列表或是其他类型中取无穷数,整个过程是在内存中,其取得值代表的无穷数也会在内存。

g=func()
for i in g:
    print(i)

每一次的取出i,都是i对应一个值,然后之前的与之前的值则是直接绑定,然后值被回收,不会占用内存

posted @ 2020-09-01 10:35  artherwan  阅读(122)  评论(0编辑  收藏  举报