一、迭代器
迭代器: 每次只能访问一个值, 且当值完全被访问后立即销毁对象
1.1 创建迭代器(iter(obj:[iterable])
)
- 返回一个
iterator
对象。 - 根据是否存在第二个实参,第一个实参的解释是非常不同的。如果没有第二个实参,
obj
必须是支持迭代协议(有__iter__()
方法)的集合对象,或必须支持序列协议(有__getitem__()
方法,且数字参数从 0 开始)
1.2 迭代器取值(next(iterator)
)
- 依次取出迭代器中的数据
- 触发迭代器对象的
__next__()
方法
s = "hello"
iterator = iter(s)
print(next(iterator))
print(next(iterator))
print(next(iterator))
print(next(iterator))
print(next(iterator))
print(next(iterator)) # 触发StopIteration
1.3 迭代器实现
class String:
def __init__(self, data):
self.data = data
self.len = len(data)
self.index = -1
def __iter__(self):
return self
def __next__(self):
if self.index < self.len-1:
self.index += 1
return self.data[self.index]
else:
raise StopIteration
string = String("hello")
print(next(string))
print(next(string))
print(next(string))
print(next(string))
print(next(string))
print(next(string))
二、生成器
生成器(Generator
)是一个用于创建迭代器的简单而强大的工具。 它们的写法类似标准的函数,但当它们要返回数据时会使用 yield
语句。 每次对生成器调用 next()
时,它会从上次离开位置恢复执行(它会记住上次执行语句时的所有数据值)
def generator(n):
a, b = 0, 1
while a < n:
yield a
a, b = b, a + b
gen = generator(10)
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
- 用生成器来完成的操作同样可以用前一节所描述的基于类的迭代器来完成。 但生成器的写法更为紧凑,因为它会自动创建
__iter__()
和__next__()
方法。 - 在于局部变量和执行状态会在每次调用之间自动保存。 这使得该函数相比使用
self.index
和self.data
这种实例变量的方式更易编写且更为清晰 - 除了会自动创建方法和保存程序状态,当生成器终结时,它们还会自动引发 StopIteration。 这些特性结合在一起,使得创建迭代器能与编写常规函数一样容易
三、对象生成式
3.1 列表对象生成式
[值 for 变量 in iterable [if 条件]]
li = [i ** 2 for i in range(10) if i % 2 != 0]
print(li) # [1, 9, 25, 49, 81]
3.2 集合对象生成式
{值 for 变量 in iterable [if 条件]}
se = {i*2 for i in range(1, 6)}
print(se) # {2, 4, 6, 8, 10}
3.3 字典对象生成式
{key: value for key, value in iterable [if 条件] }
dic = {k: v for k, v in [("1", 1), ("2", 2)]}
print(dic) # {'1': 1, '2': 2}
3.4 生成器对象生成式
(值 for 变量 in iterable [if 条件])
iterator = (i ** 2 for i in range(1, 6))
print(iterator) # <generator object <genexpr> at 0x0000017FD2FEC6D0>
print(next(iterator)) # 1
print(next(iterator)) # 4
print(next(iterator)) # 9
print(next(iterator)) # 16
print(next(iterator)) # 25