14 Python迭代器与生成器

本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)  # 报错
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章