前言
本文记录迭代器、生成器问题
一、迭代器(iterator)
对于一个可迭代的对象(Iterative),比如列表,字典,元组等等,可以使用iter()生成迭代器(iterator),将元素全部遍历完成后stopiteration。
可迭代对象(Iterative)需要定义两个函数__iter__()以及__next__(),对于我的理解,iter()相当于是迭代器(iterator)的__init__()初始化函数,可以将一个可迭代对象(Iterative)转为迭代器(iterator)。当然了,这并不能替代可迭代对象(Iterative)的初始化函数,例如下面我想对该数字生成器增加一个参数,定义生成数字的个数,这还是需要在__init__()里面定义。next()的作用向下迭代。
class MyNumbers:
def __init__(self,l):
self.l = l
def __iter__(self):
self.a = 1
return self
def __next__(self):
if self.a <= self.l:
x = self.a
self.a += 1
return x
else:
raise StopIteration
myclass = MyNumbers(10)
myiter = iter(myclass)
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
print(next(myiter))
输出
1
2
3
4
5
6
7
8
9
10
Traceback (most recent call last):
at XXXXXXXXXXXXXXXXXXX.py, line 28
at XXXXXXXXXXXXXXXXXXX.py, line 15, in __next__(self)
StopIteration:
其他可遍历对象生成迭代器(iterator):
列表:
m = ['j','f','m']
m_iter = iter(months)
print(next(m_iter))
print(next(m_iter))
print(next(m_iter))
print(next(m_iter))
输出
j
f
m
Traceback (most recent call last):
at XXXXXXXXXXXXXXXXXXX.py, line 7
StopIteration:
二、生成器(Generator)
在Python中,生成器是一种特殊的迭代器,可以通过yield语句来生成值,而不是通过return语句来一次性返回所有的值。由于生成器只在需要时才会计算下一个值,因此可以在处理大量数据时节省内存空间。
def countdown(n):
while n > 0:
yield n
n -= 1
# 获得生成器对象
c = countdown(5)
# 依次输出生成器中的值
print(next(c)) # 5
print(next(c)) # 4
print(next(c)) # 3
print(next(c)) # 2
print(next(c)) # 1
可以看到,调用 countdown(5) 返回一个生成器对象,然后通过 next() 函数来依次获取生成器中的值。每次调用 next() 函数时,生成器会从上次暂停的位置继续执行,直到遇到下一个 yield 语句,然后再次暂停。
通过列表推导式生成一个简单的生成器`
gen = (x**2 for x in range(10))
for g in gen:
print(g)
输出
0
1
4
9
16
25
36
49
64
81