本blog主要讲解Python的迭代器与生成器
- 如何通过迭代器对对象进行遍历
- 如何使类可以进行迭代
- 如何创建生成器
1. 如何通过迭代器对对象进行遍历
# 对 list创建iter
l = [1, 2]
it = iter(l)
print(next(it)) # 1
print(next(it)) # 2
print(next(it))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
# 除了可以通过next进行one-shot访问元素外,还可以通过for...in...
for i in iter(l):
print(i) # 1,2
2. 如何使类可以进行迭代
使类可以进行迭代,必须要实现两个方法分别为__iter__() 和 next()
class myNumber():
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a < 3:
x = self.a
self.a += 1
return x
else:
raise StopIteration # 如果超过3(包括3)就会raise异常表示迭代结束
my_class_iter = iter(myNumber())
print(next(my_class_iter))
print(next(my_class_iter))
# 同样可以通过for i in iter:进行遍历
for i in my_class_iter:
print(i) # 1, 2
3. 如何创建生成器
- 为什么要使用生成器, 因为如果创建列表来保存所有的元素,消耗内存很大。所以如果列表中的元素可以推算出来,那么就可以使用生成器生成列表中的每一个元素。
a = [1, 2, 3, 4, 5]
type(a) # <class 'list'>
b = (x**2 for i in range(3)) # list为中括号[], generator为小括号()
type(b) # <class 'generator'> 只是一个对象
help(b) # generator对象有_iter__和__next__方法
<genexpr> = class generator(object)
| Methods defined here:
|
| __del__(...)
|
| __getattribute__(self, name, /)
| Return getattr(self, name).
|
| __iter__(self, /)
| Implement iter(self).
|
| __next__(self, /)
| Implement next(self).
# 同样generator可以使用for i in generator:进行遍历
for i in b:
print(b) # 0 , 1, 4
- generator中保存的是算法,而不是元素,所以这是节省内存的关键。
- 使用generator生成斐波那契数列
def func_fib(max):
n, a, b = 0, 0, 1
while n < max:
print(a)
a, b = b, a + b
n = n + 1
return 'done'
func_fib(10)
# 显然fib数列是有规律的所以可以使用generator
# 只要将print改为yeild, 如果函数中含有yeild关键字,则改函数就为generator
def func_fib(max):
n, a, b = 0, 0, 1
while n < max:
yeild a
a, b = b, a + b
n = n + 1
return 'done'
# type(func_lib()) # generator
- 那如何使用yeild,yeild工作原理是什么
含有yield的函数,在调用next函数的时候,函数会运行到yield语句,并且返回后面的值,然后 保存运行的断点,当再次调用next语句的时候,会从上一次结束的断电开始继续运行知道hit到yield关键字。
def yeild_example():
print('process 1')
yield 1
print('process 2')
yield 2
generator_example = yeild_example()
b = next(generator_example)
print(b)
b = next(generator_example)
print(b)
b = next(generator_example) # 报错