注意python的编程习惯,定义函数的空行和数学符号前后的空格。
chapter9
迭代器是一个带状态的对象,在调用next()方法的时候返回容器中的下一个值,否则进入休眠状态等待被调用。
iter()函数用来创建一个可迭代对象的迭代器
my_iter=iter([1,2,3])
print(my_iter)
<list_iterator object at 0x7ff474380a90>
next()函数可以通过迭代器逐个提取可迭代对象中的值。迭代到最后,会出现StopIteration.
my_iter=iter([1,2,3])
print(next(my_iter))
print(next(my_iter))
print(next(my_iter))
print(next(my_iter))
1
2
3
Traceback (most recent call last):
File "/home/llh/Documents/full-speed-python/chapter9/test.py", line 11, in <module>
print(next(my_iter))
StopIteration
可以通过定义类Iterator classes,实现迭代器的功能。需要定义__next__()函数和__iter__()函数.注意这里不能用myrange.next()调用,会出错。
类中的__function__()函数?
class MyRange:
def __init__(self,a,b):
self.a=a
self.b=b
def __iter__(self):
return self
def __next__(self):
if self.a<self.b:
value=self.a
self.a=self.a+1
return value
else:
raise StopIteration
myrange=MyRange(1,4)
print(next(myrange))
print(next(myrange))
print(next(myrange))
print(next(myrange))
1
2
3
Traceback (most recent call last):
File "/home/llh/Documents/full-speed-python/chapter9/test.py", line 31, in <module>
print(next(myrange))
File "/home/llh/Documents/full-speed-python/chapter9/test.py", line 25, in __next__
raise StopIteration
StopIteration
MyRange(1,4)生成了一个可迭代对象,可以用于for循环。
for value in MyRange(1,4):
print(value)
1
2
3
Class Iterators,返回数字a到b的平方
class Square:
def __init__(self,a,b):
self.a = a
self.b = b
def __iter__(self):
return self
def __next__(self):
if self.a < self.b:
value = self.a
self.a += 1
return value*value
else:
raise StopIteration
square=Square(1,3)
print(next(square))
print(next(square))
print(next(square))
print(next(square))
1
4
Traceback (most recent call last):
File "/home/llh/Documents/full-speed-python/chapter9/exercise1.py", line 21, in <module>
print(next(square))
File "/home/llh/Documents/full-speed-python/chapter9/exercise1.py", line 16, in __next__
raise StopIteration
StopIteration
返回1到n的所有偶数
class Even:
def __init__(self,n):
self.num = 2
self.n = n
def __iter__(self):
return self
def __next__(self):
if self.num < self.n:
value = self.num
self.num += 2
return value
else:
raise StopIteration
ls = []
for number in Even(10):
ls.append(number)
print(ls)
[2, 4, 6, 8]
从n到0.
class Number:
def __init__(self,n):
self.n = n
def __iter__(self):
return self
def __next__(self):
if self.n >= 0:
value = self.n
self.n -= 1
return value
else:
raise StopIteration
ls = []
for value in Number(10):
ls.append(value)
print(ls)
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
数字对
class consecutive:
def __init__(self,n):
self.num = 0
self.n = n
def __iter__(self):
return self
def __next__(self):
if self.num < self.n:
value = self.num
self.num += 1
return str((value, value + 1))
#return value
else:
raise StopIteration
string = ""
for value in consecutive(6):
string = string + value
print(string)
(0, 1)(1, 2)(2, 3)(3, 4)(4, 5)(5, 6)
- 生成器 generators.
生成器一定是迭代器,迭代器不一定是生成器。
生成器在Python中是一个非常强大的编程结构,可以用更少地中间变量写流式代码。
生成器是一种特殊的迭代器,它的返回值不是通过return而是yield.
关键字yield.与return相同之处:为函数一个返回值;不同之处:每次程序需要下一个值的时候,会从yield唤醒进程,继续操作。
def myrange(a, b):
while a < b:
yield a
a += 1
for value in myrange(1, 4):
print(value)
seq = myrange(1, 3)
next(seq)
next(seq)
next(seq)
next(seq)
1
2
3
Traceback (most recent call last):
File "/home/llh/Documents/full-speed-python/chapter10/test.py", line 12, in <module>
next(seq)
StopIteration
生成器只需定义一个函数,没有迭代器定义一个类那么复杂。调用函数时返回一个生成器对象。
默认0到n
def squares(n):
for value in range(n):
yield value * value
print(squares(4))
for value in squares(4):
print(value)
<generator object squares at 0x7fd8bc047048>
0
1
4
9
从a到b
def squares(a, b):
while a < b:
yield a * a
a += 1
ls = []
for value in squares(3, 8):
ls.append(value)
print(ls)
[9, 16, 25, 36, 49]
返回序列中的所有偶数
def even(n):
for value in range(1, n):
if value % 2 == 0:
yield value
ls = []
for value in even(19):
ls.append(value)
print(ls)
[2, 4, 6, 8, 10, 12, 14, 16, 18]
从n减至0
def down(n):
while n >= 0:
yield n
n -= 1
ls = []
for value in down(10):
ls.append(value)
print(ls)
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
斐波那契数列
def fib(n):
pre = 0
cun = 1
while n > 0:
yield pre
#a = cun
#cun = pre + cun
#pre = a
pre, cun = cun, pre + cun
n -= 1
ls = []
for value in fib(10):
ls.append(value)
print(ls)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
数值对
def pairs(n):
for value in range(n):
yield str((value, value + 1))
string = ""
for value in pairs(8):
string = string + value
print(string)
(0, 1)(1, 2)(2, 3)(3, 4)(4, 5)(5, 6)(6, 7)(7, 8)