• 如何使用生成器函数实现可迭代对象?


    需求:
    实现一个可迭代对象的类,它能迭代给定范围的所有素数:
    pn = PrimeNumber(1,30)
    for k in pn:
    print k,
    输出结果:
    2 3 5 7 11 17 19 23 29

    实现过程:
    思路:
    将该类的__iter__方法实现成生成器函数,每次yield返回一个素数
    代码:

    class PrimeNumbers:
        def __init__(self,start,end):
            self.start = start
            self.end = end
    
        def isPrimeNum(self,k):
            if k < 2:    #素数指大于2的质数,这里排除小于2的数
                return False
    
            for i in range(2,k):   #如果能被k和1以外的数整除,返回False,非素数
                if k % i == 0:
                    return False
    
            return True    # 前面都通过了,返回True,这里的k为素数
    
        def __iter__(self):  # 构建生成器:(集可迭代对象和迭代器的特性于一身,包括了__iter__和__next__方法,yiled是__next__方法的另一种表现形式)
            for k in range(self.start,self.end + 1):
                if self.isPrimeNum(k):
                    yield k
    
    if __name__=='__main__':
        list_number = []
        for x in PrimeNumbers(1,100):
            list_number.append(x)
        print(list_number)
    
    =====================================================================================================================
    
    from collections import Iterable
    
    class PrimeNumbers(Iterable):
        def __init__(self,a,b):
            self.a = a
            self.b = b
    
        def __iter__(self):
            for k in range(self.a,self.b+1):
                if self.is_prime(k):
                    yield k
    
        def is_prime(self,k):
            return False if k < 2 else all(map(lambda x:k % x,range(2,k)))
    
    pn = PrimeNumbers(1,30)
    for n in pn:
        print(n)
    
    ====================================================================================
    >>> def f():  
    ...     print('in f 1')
    ...     yield 1
    ...     print('in f 2')
    ...     yield 2
    ...     print('in f 3')
    ...     yield 3
    ... 
    
    >>> f()  # 包含yield的即为生成器对象,生成器对象同时有__iter__和__next__方法,使用生成器对象的好处是可以自动维护迭代状态。
    <generator object f at 0x7f794c42ea40>
    
    >>> g = f()
    
    >>> from collections import Iterable,Iterator
    
    >>> isinstance(g,Iterator)
    True
    
    >>> isinstance(g,Iterable)
    True
    
    >>> iter(g) is g
    True
    
    >>> next(g)
    in f 1
    1
    
    >>> next(g)
    in f 2
    2
    
    >>> next(g)
    in f 3
    3
    
    >>> next(g)
    ---------------------------------------------------------------------------
    StopIteration                             Traceback (most recent call last)
    <ipython-input-169-e734f8aca5ac> in <module>
    ----> 1 next(g)
    
    StopIteration: 
    
    >>> g = f()
    
    >>> for x in g:
    ...     print(x)
    ... 
    in f 1
    1
    in f 2
    2
    in f 3
    3
    
    >>> class XXX_Iterable(Iterable):
    ...     def __iter__(self):
    ...         yield 1
    ...         yield 2
    ...         yield 3
    ... 
    
    >>> x = XXX_Iterable()
    
    >>> 5 % 2
    1
    
    >>> if 5 % 2:
    ...     print(aaa)
    ... 
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-175-d8374d02d066> in <module>
          1 if 5 % 2:
    ----> 2     print(aaa)
          3 
    
    NameError: name 'aaa' is not defined
    
    >>> if 5 % 2:
    ...     print('aaa')
    ... 
    ... 
    aaa
    
    >>> 5 % 2 is True
    False
    
    >>> 4 % 2
    0
    
    >>> if 4 %2:
    ...     print('bbb')
    ... 
    
    >>> for x in range(2,10):
    ...     print(x)
    ... 
    2
    3
    4
    5
    6
    7
    8
    9
    
    >>> def is_prime(k):
    ...     if k < 2:
    ...         return False
    ...     for x in range(2,k):
    ...         if k % x == 0:
    ...             return False
    ...         return True
    ... 
    
    >>> is_prime(2)
    
    >>> range(2,2)
    range(2, 2)
    
    >>> for x in range(2,2)
      File "<ipython-input-184-19ce5b84b352>", line 1
        for x in range(2,2)
                           ^
    SyntaxError: invalid syntax
    
    
    >>> for x in range(2,2):
    ...     print(x)
    ... 
    
    >>> for x in range(2):
    ...     print(x)
    ... 
    0
    1
    
    >>> is_prime(4)
    False
    
    
  • 相关阅读:
    天气渐凉,意渐浓
    WebBrowser 多线程 DocumentCompleted 和定时器
    浅谈 Glide
    浅谈 maxMemory , totalMemory , freeMemory 和 OOM 与 native Heap
    XGoServer 一个基础性、模块完整且安全可靠的服务端框架
    GreenDao 兼容升级,保留旧数据的---全方面解决方案
    基于 xorm 的服务端框架 XGoServer
    全面总结: Golang 调用 C/C++,例子式教程
    通俗易懂,各常用线程池的执行 流程图
    为什么我的子线程更新了 UI 没报错?借此,纠正一些Android 程序员的一个知识误区
  • 原文地址:https://www.cnblogs.com/Richardo-M-Q/p/13264178.html
Copyright © 2020-2023  润新知