python进阶(小白也能看懂)——生成器与迭代器

python进阶(小白也能看懂)——生成器与迭代器

第二篇

1 例子

先给出生成器与迭代器的例子,然后详细讲解需要理解的知识。

1.1 生成器

# 生成器
a = (i+1 for i in range(10))
# 列表推导式,不是生成器
b = [i+1 for i in range(10)]
# 生成器
def generator(n):
	z = 1
	while z<n:
		z += 1
		yield z
	return "done"
c = generator(5)
# 如果不信可以使用print验证
print(a,b,c,sep="\n")

输出结果

<generator object <genexpr> at 0x000001D1B1E48570>
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
<generator object generator at 0x000001D1B2E8A138>

1.2 迭代器

# 迭代器
class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1

    # 返回迭代器对象本身
    def __iter__(self):
        return self

    # 返回容器下一个元素
    def __next__(self):
        self.a, self.b = self.b, self.a + self.b
        return self.a
d = Fib()
# 判断d是否为迭代器
isinstance(d, Iterator)

输出结果

True

2 什么是生成器与迭代器

在 Python 中,迭代器是指遵循迭代器协议(iterator protocol)的对象。
迭代器协议:任意对象只要定义了__iter__方法和__next__方法就是迭代器,就像上面例子给出的一样。

再说明一下与迭代器相关的名词:迭代与可迭代对象

迭代(Iteration):当我们用一个循环(比如 for 循环)来遍历容器(比如列表,元组)中的元素时,这种遍历的过程就叫迭代。

可迭代对象(Iterable):直观上可以用for循环遍历的对象就是可迭代对象。 严格地定义说,Python中任意的对象,只要它定义了可以返回⼀个迭代器的__iter__⽅法,或者定义了可以⽀持下标索引的__getitem__⽅法,那么它就是⼀个可迭代对象。

2.1 迭代器与可迭代对象的区别

相同点:都可以使用for循环取出元素。
不同点:迭代器一定是可迭代对象,但可迭代对象不一定是迭代器。迭代器可以使用python内置的next方法一个一个取出元素,而可迭代对象不行。(从上面的定义也可以看出,因为可迭代对象没有实现__next__方法)

iterator = (i+1 for i in range(5)) # 迭代器
iterable = [i+1 for i in range(5)] # 可迭代对象

# 判断itrable为可迭代对象
from collections import Iterable
isinstance(iterator, Iterable) # True
isinstance(iterable, Iterable) # True 
hasattr(iterable,'__iter__')   # True 
hasattr(iterable,'__getitem__' # True

# 判断iterator是否为迭代器
from collections import Iterator
isinstance(iterator, Iterator) # True
isinstance(iterable, Iterator) # False 

# iterator可以使用next方法
next(iterator) # 1
# iterable不能使用next方法
next(iterable) # 'list' object is not an iterator

2.2 为什么使用迭代器

与列表不同,迭代器不会把元素一次性加载到内存,而是以延迟方式加载。如列表中含有一千万个整数,需要占超过400M的内存,而迭代器只需要几十个字节的空间。因为它并没有把所有元素装载到内存中,而是等到调用 next 方法时候才返回该元素。这样就不会消耗大量资源。(在使用for循环迭代的过程中,本质上是调用迭代器的next方法取出元素)

2.3 生成器——一种特殊的迭代器

生成器(generator)也是一种迭代器,它有和迭代器一样的特性,唯一的区别在于生成器的构造方式更加简洁。它通常采用yield将函数构造生成器或者使用生成器表达式()构造生成器。具体如何构造可以参考1.1 生成器的例子

3 参考

极客学院——生成器
极客学院——迭代器
生成器与迭代器

发布了84 篇原创文章 · 获赞 113 · 访问量 35万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章