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