Python迭代器

2018-07-17  本文已影响0人  小学弟_

1.迭代和可迭代协议

    1)什么叫迭代

        for i in [1,2,3,4]: 

            print(i)

        结果:

            1

            2

            3

            4

        for i in 1234

            print(i) 

        结果:

        Traceback (most recent call last):

          File "test.py", line 4, in 

            for i in 1234:

        TypeError: 'int' object is not iterable 

        错误说,我们的1234不可迭代。上面的却可以。

        那么大胆推测,如果可以迭代,就应该可以被for循环。

        我们知道,字符串、列表、元祖、集合、字典都可以for循环

        说明他们都是可迭代的。

        那么正确的路子应该是什么样的呢,总不能凭空想象。

        from collections import Iterable 

        s = '1234'

        l = [1,2,3,4] 

        t = (1,2,3,4) 

        d = {1:2,3:4} 

        s = {1,2,3,4}

        print(isinstance(a,Iterable))#Ture 

        print(isinstance(l,Iterable))#Ture

        print(isinstance(t,Iterable))#Ture

        print(isinstance(d,Iterable))#Ture

        print(isinstance(s,Iterable))#Ture

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

    2)可迭代协议

        可以被迭代满足的要求就叫做可迭代协议。

        可迭代协议;就是内部实现了 __iter__() 方法

        验证:

            print(dir([1,2]))

            print(dir((1,2)))

            print(dir({1:2}))

            print(dir({1,2}))

        总结:

            可以被for循环的都是可迭代的,想要可迭代,内部必须有一个

            __iter__() 方法。

            接着分析,这个 __iter__()做了什么事情?

            print([1,2].__iter__())

            结果

            

            这里的iterator就是迭代器。

2.迭代器

    可迭代后又一难题出现了,什么叫“迭代器”?

    '''

    dir([1,2].__iter__())是列表迭代器中实现的所有方法,

    dir([1,2])是列表中实现的所有方法,都是以列表的形式返

    回给我们的,为了看的更清楚,我们分别把他们转换成集合,

    然后取差集。

    '''

    #print(dir([1,2].__iter__()))

    #print(dir([1,2]))

    print(set(dir([1,2].__iter__()))-set(dir([1,2])))

    结果:

    {'__length_hint__', '__next__', '__setstate__'}

    我们看到在列表迭代器中多了三个方法,那么这三个方法都是

    干什么的呢?

        iter_l = [1,2,3,4,5,6].__iter__()#列表迭代器

        #获取迭代器中元素的长度

        print(iter_l.__length_hint__())

        #根据索引值指定从哪里开始迭代

        print('*',iter_l.__setstate__(4))

        #一个一个的取值

        print('**',iter_l.__next__())

        print('***',iter_l.__next__())

        结果:

            6

            * None

            ** 5

            *** 6

    这三个方法中,能够一个一个取值的方法就是 __next__()

    在for循环中,就是在内部调用了 __next__() 方法才能取到

    一个一个的值。

    例子:

        l = [1,2,3]

        l_iter = l.__iter__()

        item = l_iter.__next__()

        print(item)#1

        item = l_iter.__next__()

        print(item)#2

        item = l_iter.__next__()

        print(item)#3

        item = l_iter.__next__()

        print(item)#StopIteration

        注意:

            如果我们一直取,直到next取到迭代器里已经没有元素了,

            就会抛出一个StopIteration异常,告诉我们,列表中已经

            没有有效元素了。

            这个时候,我们就要使用异常处理机制来把这个异常处理掉。

            例子:

                lis = ['1', '2', '3']

                it = lis.__iter__()

                while 1:

                    try:

                        res = it.__next__()

                        print(res)

                    except StopIteration:

                        break

                结果:

                    1

                    2

                    3

    注:

        迭代器遵循迭代器协议:必须拥有 __iter__()方法和__next__()方法。

        # 迭代器的特点:

        #   1. 节省内存

        #   2. 惰性机制

        #   3. 只能往前拿. 不能反着拿

3.判断对象是迭代器还是可迭代对象

    例子:

        from collections import Iterator

        from collections import Iterable

        print(isinstance(range(10), Iterator))#False

        print(isinstance(range(10), Iterable))#Ture

        >>> from collections import Iterator

        >>> isinstance((x for x in range(10)), Iterator)

        True

        >>> isinstance([], Iterator)

        False

        >>> isinstance({}, Iterator)

        False

        >>> isinstance('abc', Iterator)

        False

        >>> from collections import Iterable

        >>> isinstance([], Iterable)

        True

        >>> isinstance({}, Iterable)

        True

        >>> isinstance('abc', Iterable)

        True

        >>> isinstance((x for x in range(10)), Iterable)

        True

        >>> isinstance(100, Iterable)

        False

上一篇下一篇

猜你喜欢

热点阅读