迭代器

一、定义

  1.iterator.(迭代器)

  2.iterable.(可迭代的)

    一般来说,可以被for循环的就是可以迭代的,迭代器一定可以迭代,但是可迭代的类型不一定是迭代器。

二、说明

  1.有__iter__方法,说明可迭代

def shili1():
    print(dir([]))     
#告诉我列表拥有的所有方法
    print(dir(()))
    print(dir(''))
    print(dir(range(10)))

    ret=set(dir([]))&set(dir(''))&set(dir({}))&set(dir(range(10)))
    print(ret)    
#有一个'__iter__'

   判断一下这些类型有没__iter__方法

print('__init__' in dir(int))
print('__init__' in dir(list))
print('__init__' in dir(dict))
print('__init__' in dir(set))
print('__init__' in dir(tuple))
print('__init__' in dir(enumerate))
print('__init__' in dir(range(10)))
print('__iter__' in dir(int))           #false
print('__iter__' in dir(bool))      #false
print('__iter__' in dir(list))
print('__iter__' in dir(dict))
print('__iter__' in dir(set))
print('__iter__' in dir(tuple))
print('__iter__' in dir(enumerate))
print('__iter__' in dir(range(10)))

  2.#setstate指定从那个位置开始取(一般是从0位开始)

   一个可迭代的类型执行了iter之方法后的返回值就是一个迭代器

print(set(dir([].__iter__())) - set(dir([])))
# {'__setstate__', '__next__', '__length_hint__'}

  3.示例1(可迭代的不一定是迭代器,迭代器一定可迭代)

print('*'*40)
l=[1,2,3]
iterator=l.__iter__()
print(iterator.__next__())   #l内部没有next方法,调用iter之后的返回值有next
print(iterator.__next__())   #l内部没有next方法,调用iter之后的返回值有next
print(iterator.__next__())   #l内部没有next方法,调用iter之后的返回值有next
# print(iterator.__next__())   #报错
# 不能被循环的: not iterable(不可迭代的)   ->    __iter__   ->只要含有iter就可迭代且都可以被for循环   ->   可迭代协议

  4.创建一个iterator

#[].__iter__()拿到一个
#可迭代协议
#在for循环时先找__iter__方法,如果没有就
#迭代器协议->内部含有next方法和__init__方法的就是迭代器
print('__iter__' in dir([].__iter__()))

from collections import Iterable
from collections import Iterator

print(isinstance([],Iterator))  #isinstace判断是否是。迭代器,迭代类型。列表不是迭代器,但是可迭代。
print(isinstance([],Iterable))

class A:
    # def __init__(self):pass
    def __next__(self):pass      #同时有next和init就是迭代器。next可以一个一个获取值
    # def __iter__(self):pass    #有iter就可用被迭代

a=A()
print(isinstance(a,Iterable))
print(isinstance(a,Iterator))

#只要是迭代器一定可迭代,可迭代的不一定是迭代器
#可迭代的.__init__()方法可以得到一个迭代器

三、作用
  使用迭代器的好处是可以节省内存空间

#用迭代器的好处:从容器类型中一个一个的取值,会把所有值都取到
# 可以节省内存空间(迭代器并不会再占用一大块内存,而是随着循环,每次生成一个,每次next给一个
#range,文件句柄
#range->
print(range(100000000))   #range(0, 100000000)   得到可迭代对象,但此时并没有生成数据
print(list(range(10000000000000)))    #内存错误
print(list(range(10)))    #[0,1,2,……,9]

#f=open ->


#没有for循环,依然可以遍历
l=[1,2,3,4]
iterator=l.__iter__()
while True:
    print(iterator.__next__())#虽然会报错,但是也一个个输出了   最后抛出StopIterator

 四、总结

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

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

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

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

  5.迭代器一定可迭代,可迭代的通过调用__iter__方法可以得到一个迭代器

  6.迭代器的特点:

    1)方便使用,且只能取所有的数据取一次。下次重新取。

    2)节省内存空间(当前和取下一个数据)

posted @ 2019-06-09 15:41  玉石非玉  阅读(94)  评论(0编辑  收藏  举报