本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) # 報錯