迭代器与生成器

1 简介

list,tuple,dict,set都是容器,容器是可迭代对象,可迭代对象通过调用iter()函数可以得到一个迭代器。

迭代器可以通过next()函数来得到下一个元素,从而支持遍历。

生成器,迭代器,可迭代对象,容器,他们之间的关系。图片来自https://nvie.com/posts/iterators-vs-generators/

参考https://zhuanlan.zhihu.com/p/26123333

2 可迭代对象(iterable)

可直接作用于for循环的对象统称为Iterable,具体的实现是,Python 中的对象只要定义了__iter__方法(该方法返回一个迭代器对象)就是可迭代对象。

容器,list,tuple,dict,set是可迭代对象,是迭代器吗?

from collections import Iterable,Iterator

items = [123,"123",[1,2,3],(1,2,3),{"a":1,"b":2},{1,2,3}]
for item in items:
    temp = "{0}的类型是{1},它是可迭代对象:{2},它是迭代器:{3}".format(item,type(item),isinstance(item,Iterable),isinstance(item,Iterator))
    temp2 = "实现了__iter__方法{0}".format("__iter__" in dir(item))
    print(temp,"\n")
    print(temp2, "\n")

结果

123的类型是<class 'int'>,它是可迭代对象:False,它是迭代器:False 

实现了__iter__方法False 

123的类型是<class 'str'>,它是可迭代对象:True,它是迭代器:False 

实现了__iter__方法True 

[1, 2, 3]的类型是<class 'list'>,它是可迭代对象:True,它是迭代器:False 

实现了__iter__方法True 

(1, 2, 3)的类型是<class 'tuple'>,它是可迭代对象:True,它是迭代器:False 

实现了__iter__方法True 

{'a': 1, 'b': 2}的类型是<class 'dict'>,它是可迭代对象:True,它是迭代器:False 

实现了__iter__方法True 

{1, 2, 3}的类型是<class 'set'>,它是可迭代对象:True,它是迭代器:False 

实现了__iter__方法True 

str,list,tuple,dict,set是可迭代对象,不是迭代器,没有实现__iter__方法

 

3 迭代器(iterator)

由上面可知str,list,tuple,dict,set是可迭代对象,不是迭代器

字符串,列表可以通过索引来去除元素,而集合没有索引,想取出其中的元素,就是不依赖于索引的方式,也就是迭代器。

可作用于next()函数的对象都是Iterator。具体的实现是,任何对象只要定义了__iter__和__next__方法,那就是迭代器对象

创建迭代器

lis = [1,2,3,4]
lis2 = iter(lis)
print(type(lis2))
print("__next__" in dir(lis))
print("__next__" in dir(lis2))

结果

<class 'list_iterator'>
False
True

所以str,list,tuple,dict,set通过调用iter()函数就创建了迭代器,实现了__iter__和__next__方法

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

  1.     迭代器实现了__iter__和__next__方法
  2.     可迭代对象只实现了__iter__方法,没有实__next__方法

4 生成器(generator)

        生成器就是一种特殊的迭代器,不过它的实现方式更为简单优雅,同样我们可以明确的是,任何生成器都是迭代器

生成器是懒人方式的迭代器。

        在迭代器中,如果要枚举它的元素,这些元素需要提前生成。试想,如果元素有1千万,是不是比较占内存。生成器中的元素没有提前生成好,而是通过调用next()函数来生成下一个元素。

        创建生成器的方式:

  1. 通过小括号()
  2. 通过yield关键字

    在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。调用一个生成器函数,返回的是一个迭代器对象。

来自https://www.runoob.com/python3/python3-iterator-generator.html

5 总结

字符串和容器(列表,元组,字典,集合)是可迭代对象,它实现了__iter__方法,

通过调用iter()方法创建了迭代器,迭代器实现了__iter__和__next__方法,

生成器是特殊的迭代器,它的元素在调用next()函数时才生成,与迭代器比,节省内存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值