zoukankan      html  css  js  c++  java
  • python-多任务编程03-迭代器(iterator)

    迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

    可迭代对象(Iterable)

    能够被循环遍历(迭代)的对象称为可迭代对象,如list、tuple、dict、set、str等。使用以下语句判断是否是可迭代对象

    >>> from collections.abc 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

    从代码层面上来说,当class中实现了__iter__方法,则该类创建的对象即为可迭代对象

    >>> class MyList(object):
    ...     def __init__(self):
    ...             self.container = []
    ...     def add(self, item):
    ...             self.container.append(item)
    ...     def __iter__(self):
    ...             """返回一个迭代器"""
    ...             # 我们暂时忽略如何构造一个迭代器对象
    ...             pass
    ...
    >>> mylist = MyList()
    >>> from collections import Iterable
    >>> isinstance(mylist, Iterable)
    True
    >>>
    # 这回测试发现添加了__iter__方法的mylist对象已经是一个可迭代对象了

    可迭代对象的本质

    可迭代对象的本质就是可以提供一个迭代器,该迭代器能记录每次访问到了第几条数据,以便每次迭代都可以返回下一条数据。

    迭代器(Iterator)

    要使得可迭代对象能够正常的循环迭代,必须实现__iter__方法返回一个迭代器。我们在迭代一个可迭代对象的时候,实际上就是先获取该对象提供的一个迭代器,然后通过这个迭代器来依次获取对象中的每一个数据。

    要自定义一个迭代器,必须实现__iter__方法和__next__方法。例:

    from collections.abc import Iterable
    import time
    
    
    class MyList(object):
        """自定义一个可迭代对象"""
    
        def __init__(self):
            self.content = list()
    
        def add(self, item):
            self.content.append(item)
    
        def __iter__(self):
            # 1.要使一个对象是可迭代对象,必须实现__iter__方法
            # 2.要使一个对象迭代时能每次都返回一个值,必须让__iter__返回一个迭代器对象
            # 创建迭代器对象
            myiterator = MyIterator(self)
            return myiterator
    
    
    class MyIterator(object):
        """自定义一个迭代器,必须实现__iter__方法和__next__方法"""
    
        def __init__(self, mylist_obj):
            self.mylist = mylist_obj
            self.current = 0
    
        def __iter__(self):
            pass
    
        def __next__(self):
            """每次迭代时返回的值实际是通过__next__方法返回的"""
            # 1.定义一个下标current,每次调用时+1,用来实现每次调用__next__时,返回下一个值
            # 2.注意判断下标current自增时是否会越界,若越界则手动抛出StopIteration异常
            #   外层for循环迭代时,若遇到StopIteration异常,则会停止迭代
            if self.current == len(self.mylist.content):
                raise StopIteration
            value = self.mylist.content[self.current]
            self.current += 1
            return value
    
    
    def main():
        my_list = MyList()
        my_list.add(11)
        my_list.add(22)
        my_list.add(33)
        print('my_list是不是可迭代对象:', isinstance(my_list, Iterable))
        my_list_iterator = iter(my_list)
        print('my_list返回的迭代器为:', my_list_iterator)
        print('my_list的下一个值为:', next(my_list_iterator))
        for i in my_list:
            print(i)
            time.sleep(1)
    
    
    if __name__ == '__main__':
        main()

    运行结果为:

     上述代码定义了两个类,共同实现一个可迭代对象,我们可以将第二个迭代器类中使用到的方法放到第一个可迭代对象中,这样第一个可迭代对象同时也是一个迭代器。__iter__方法返回的就是自己self,如:

    import time
    
    
    class MyList(object):
        """自定义迭代器"""
    
        def __init__(self):
            self.content = list()
            self.current = 0
    
        def add(self, value):
            self.content.append(value)
    
        def __iter__(self):
            return self
    
        def __next__(self):
            # 若越界则抛出StopIteration异常
            if self.current == len(self.content):
                raise StopIteration
            # 不越界则返回当前迭代的值,并自增下标current
            value = self.content[self.current]
            self.current += 1
            return value
    
    
    def main():
        # 创建迭代器对象
        my_list = MyList()
      print('my_list是不是一个可迭代对象', isinstance(my_list, Iterable))
      print('my_list是不是一个迭代器', isinstance(my_list, Iterator))
    # 添加值
        my_list.add('小明')
        my_list.add('小红')
        my_list.add('小花')
        # 遍历my_list
        for value in my_list:
            print(value)
            time.sleep(0.5)
    
    
    if __name__ == '__main__':
        main()

    运行结果为:

     迭代器实现斐波那契数列

    import time
    
    
    class Fibonacci(object):
        def __init__(self, num):
            self.a = 0
            self.b = 1
            self.num = num
            self.current = 0
    
        def __iter__(self):
            return self
    
        def __next__(self):
            if self.current == self.num:
                raise StopIteration
            temp = self.a
            self.a, self.b = self.b, self.a + self.b
            self.current += 1
            return temp
    
    
    def main():
        fibonacci_1 = Fibonacci(10)
        fibonacci_2 = Fibonacci(5)
        fibonacci_3 = Fibonacci(8)
        # for循环接收可迭代对象
        for i in fibonacci_1:
            print(i)
            time.sleep(0.2)
        # list接收可迭代对象
        lst = list(fibonacci_2)
        print(lst)
        # tuple接收可迭代对象
        tpl = tuple(fibonacci_3)
        print(tpl)
    
    
    if __name__ == '__main__':
        main()

    运行结果为:

  • 相关阅读:
    Visio 2003 怎样将用例图画的更美观些
    Mvc项目实例 MvcMusicStore 四
    Mvc项目实例 MvcMusicStore 三
    Lock 会引起死锁吗
    进程和线程
    vb.net winform pos机并口打印机打印以及开钱箱。。。。
    .net winfrom 定义全局快捷键!
    WebBrowser中HTML的js与winform中其他的窗体调用。。。
    [转]确认网络环境3G/WIFI
    图片分割的代码
  • 原文地址:https://www.cnblogs.com/gcxblogs/p/12945017.html
Copyright © 2011-2022 走看看