需求:
实现一个可迭代对象的类,它能迭代给定范围的所有素数:
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