在 Python 中,迭代器(Iterator)是一个访问集合元素的对象,它能够实现遍历集合的所有元素,而无需了解集合底层结构和细节。Python 中所有可迭代的对象(如 列表、元组、字符串、字典、集合等)都可以通过内置函数 iter() 获取对应的迭代器,然后使用内置函数 next() 逐个获取元素。当集合中的所有元素被遍历完成后,再次使用 next() 函数会抛出 StopIteration 异常。
在 Python 中,可迭代对象(Iterable)是指可以被迭代的对象,也就是包含多个元素并且支持使用 for 循环语句进行遍历的对象。Python 中许多内置的数据类型都属于可迭代对象,包括列表、元组、字符串、字典、集合等。
我们可以使用isinstance()方法和collections.abc中的Iterable类型来检查一个东西是否为可迭代对象。
例:
from collections.abc import Iterable
a = {1:"1",2:[1,2,3]}
print(isinstance(a,Iterable))
True
返回值为True
python中有很多内置类型就是可迭代对象,可迭代对象就说明这个东西可以通过iter()方法变为迭代器,举一个列表的例子。
a = [1,2,3]
a这个列表就是一个可迭代对象,我们先通过instance()方法检查这个列表是否为可迭代对象。
print(isinstance(a,Iterable))
True
for i in a:
print(i)
注意:python在进行for 语句遍历循环的时候,会隐式的把需要遍历的对象转换成迭代器,并不断调用迭代器中的__next__()魔法函数,把迭代器中的对象一个一个的返回出来。
class Iterable(object):
def __init__(self):
pass
def __iter__(self):
return self
def __next__(self):
pass
if __name__ == '__main__':
i = Iterable()
这个是自定义迭代器的一个基本模板,除了初始化方法__init__()之外还有__iter__、next__两个魔法方法,这两个方法前者负责返回自身,所以它的返回值必须是self,而__next()方法负责迭代器主要的业务逻辑,需要根据不同的情况编写。
这里举一个经典的斐波那契额数列的例子:
class Fib:
def __init__(self):
self.prev,self.cur = 0,1
def __iter__(self):
return self
def __next__(self):
self.cur,self.prev = self.cur + self.prev,self.cur
return self.cur
def fib():
cur,prev = 1,0
while 1:
yield cur
cur,prev = cur + prev,prev
if __name__ == '__main__':
fib = Fib()
for i in range(10):
print(next(fib))
这段代码中的带yield的fib()函数是生成器函数
生成器(Generator)是一种特殊的迭代器,它使用 yield 语句来产生值。与普通的迭代器相比,生成器更加简洁、高效,能够在遍历元素的同时动态生成新的元素,而不会像列表解析那样一次性占用大量内存空间。
def my_generator():
yield 1
yield 2
yield 3
yield 4
for item in my_generator():
print(item) # 依次输出 1, 2, 3, 4
控制台会依次输出 1, 2, 3, 4
上述代码是构建生成器的两种方式之一,也就是用函数来构建。
def my_generator():
yield 1
yield 2
yield 3
yield 4
# for item in my_generator():
# print(item) # 依次输出 1, 2, 3, 4
print(my_generator())
<generator object my_generator at 0x0000018F46583C10>
当打印这个执行函数时,控制台会返回这个信息,这个信息说明该函数返回的是一个generator (也就是生成器)对象。
生成器对象可以在当他被遍历的时候,自动调用__iter__()方法和__next__()方法,而且生成器是用一种懒加载的模式生成值,所以不需要担心生成器生成的值会一次性写入内存中,它会一个一个的写入内存。
g = (i for i in range(5))
用类似这样的表达式就能生成一个生成器,现在g就是一个迭代器,同时也是生成器。
from collections.abc import Iterable
g = (i for i in range(5))
print(isinstance(g,Iterable)) # 返回值为True
print(iter(g)) # at 0x00000125451E3C10>
注意:生成器也可以是一个可迭代对象,因此我们可以遍历它:
for i in g:
print(i)