python 可迭代对象,迭代器,生成器的区别及使用
可迭代对象
可迭代对象类型:list,dict,tuple,str,set,deque等
如何判断一个对象是否是可迭代对象,可以通过
dir()方法看它里面有没有__iter__方法,如果有这个方法就是可迭代对象。
迭代器对象
上述的可迭代对象类型都不是迭代器,那什么是迭代器?
迭代器对象相对可迭代对象无非就是多了个
__next__方法。
所以迭代器是在可迭代的基础上实现的。要创建一个迭代器,我们首先得有一个可迭代对象。
现在就来看看,如何创建一个可迭代对象,并以可迭代对象为基础创建一个迭代器。
from collections.abc import Iterable, Iterator, Generator
class Aiterable(object):
def __init__(self, num):
self.start = num
def __iter__(self):
return Aiterator(self.start) # 返回一个迭代器
class Aiterator(object):
def __init__(self, start):
self.start = start
def __iter__(self):
return self
def __next__(self):
if self.start > 0:
self.start = self.start-1
return self.start
raise StopIteration
if __name__ == '__main__':
a = Aiterable(5)
print(isinstance(a,Iterable)) # True
print(isinstance(a,Iterator)) # False
t = Aiterator(5)
print(isinstance(t,Iterator)) # True 正式因为Aiterator里面有__next__方法
iter = iter(a)
print(isinstance(iter,Iterator)) # True
print(iter.__next__())
print(iter.__next__())
print(iter.__next__())
print(iter.__next__())
for循环的过程就是将可迭代对象转换为迭代器对象,再不断调用__next__方法
生成器
生成器是在迭代器的基础上,再实现了
yield
生成器的创建方式有两种
- 列表生成式
L = (x*x for x in range(10))
print(isinstance(L,Generator)) # True
- 实现
yield函数
# 实现了yield的函数
def mygen(n):
now = 0
while now < n:
yield now
now += 1
if __name__ == '__main__':
gen = mygen(10)
print(isinstance(gen, Generator)) # True
生成器的激活/运行方式有两种
- 使用
next() - 使用
gengerator.send(None)
示例:
def mygen(n):
now = 0
while now < n:
yield now
now += 1
if __name__ == '__main__':
gen = mygen(4)
# 通过交替执行,来说明这两种方法是等价的。
print(gen.send(None))
print(next(gen))
print(gen.send(None))
print(next(gen))
生成器的执行状态
- GEN_CREATED 等待开始执行
- GEN_RUNNING 解释器正在执行(只有在多线程应用中才能看到这个状态)
- GEN_SUSPENDED 在yield表达式处暂停
- GEN_CLOSED 执行结束
示例:
from inspect import getgeneratorstate
def mygen(n):
nums = 0
while nums < n:
yield nums
nums += 1
raise StopIteration # 注意自己编写生成器时要在结束时抛stop异常
if __name__ == '__main__':
gen = mygen(2)
print(getgeneratorstate(gen))
print(next(gen))
print(getgeneratorstate(gen))
print(next(gen))
gen.close() # 手动关闭/结束生成器
print(getgeneratorstate(gen))
向生成器发送消息
def mygen(n):
nums = 0
while nums < n:
# rec = yield可以接收外部程序通过send()发送的信息,并赋值给rec
rec = yield nums # yield nums是将nums return给外部调用程序。
if rec is None:
rec = 1
nums += rec
raise StopIteration
if __name__=="__main__":
gen = mygen(10)
print(next(gen)) # 【坑】注意第一次一定要next或者send(None)来启动
print(gen.send(2))
print(next(gen))
print(gen.send(4))
# 输出
0
2
3
7
python 可迭代对象,迭代器,生成器的区别及使用的更多相关文章
- python 可迭代对象 迭代器 生成器总结
可迭代对象 只要有魔法方法__iter__的就是可迭代对象 list和tuple和dict都是可迭代对象 迭代器 只要有魔法方法__iter__和__next__的就是可迭代对象 生成器 只要含有y ...
- 可迭代对象&迭代器&生成器
在python中,可迭代对象&迭代器&生成器的关系如下图: 即:生成器是一种特殊的迭代器,迭代器是一种特殊的可迭代对象. 可迭代对象 如上图,这里x是一个列表(可迭代对象),其实正如第 ...
- 【Python】【容器 | 迭代对象 | 迭代器 | 生成器 | 生成器表达式 | 协程 | 期物 | 任务】
Python 的 asyncio 类似于 C++ 的 Boost.Asio. 所谓「异步 IO」,就是你发起一个 IO 操作,却不用等它结束,你可以继续做其他事情,当它结束时,你会得到通知. Asyn ...
- 深入理解python中可迭代对象,迭代器,生成器
英文原文出处:Iterables vs. Iterators vs. Generators 在python学习中,通常会陷入对以下几个相关概念之间的确切差异的困惑中: a container(容器) ...
- Python--可迭代对象,迭代器,生成器
记得在刚开始学Python的时候,看到可迭代对象(iterable).迭代器(iterator)和生成器(generator)这三个名词时,完全懵逼了,根本就不知道是啥意识.现在以自己的理解来详解下这 ...
- Python迭代器,可迭代对象,生成器
迭代器 迭代器(iterator)有时又称游标(cursor)是程式设计的软件设计模式,可在容器物件(container,例如链表或阵列)上遍访的界面,设计人员无需关心容器物件的内存分配的实现细节. ...
- Python可迭代对象、迭代器和生成器
Python可迭代对象.迭代器和生成器 python 函数 表达式 序列 count utf-8 云栖征文 python可迭代对象 python迭代器 python生成器 摘要: 8.1 可迭代对象( ...
- 搞清楚 Python 的迭代器、可迭代对象、生成器
很多伙伴对 Python 的迭代器.可迭代对象.生成器这几个概念有点搞不清楚,我来说说我的理解,希望对需要的朋友有所帮助. 1 迭代器协议 迭代器协议是核心,搞懂了这个,上面的几个概念也就很好理解了. ...
- 11.Python初窥门径(函数名,可迭代对象,迭代器)
Python(函数名,可迭代对象,迭代器) 一.默认参数的坑 # 比较特殊,正常来说临时空间执行结束后应该删除,但在这里不是. def func(a,l=[]): l.append(a) return ...
- Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器
Python进阶(三)----函数名,作用域,名称空间,f-string,可迭代对象,迭代器 一丶关键字:global,nonlocal global 声明全局变量: 1. 可以在局部作用域声明一 ...
随机推荐
- 伪造ip头
x-forwarded-for: 127.0.0.1x-remote-IP: 127.0.0.1x-remote-ip: 127.0.0.1x-client-ip: 127.0.0.1x-client ...
- 【转载】Kafka介绍及升级经验分享
http://blog.talkingdata.net/?p=3165 背景 当时的现状:开始使用Kafka的时候,使用的版本是0.7.2,当时的目的是为了替代kestrel,主要是使用Kafka来做 ...
- lync sdk 二次开发
1.关于 UI Suppression Mode http://blog.thoughtstuff.co.uk/2014/08/the-6-things-you-need-to-know-about- ...
- 四. (TDZ)展示性死区
在ES6中怎么使用 var Let const ? 1.var 声明之前 2. let 声明之前 3. const声明之前
- leetcode-129-求根到叶子结点数字之和
题目描述: 第一次提交: # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): # self. ...
- [JZOJ4633] 【GDOI2017模拟7.15】萌萌哒
题目 描述 题目大意 给你一个数列,接下来有许多个操作,使得区间[l1,r1][l_1,r_1][l1,r1]和[l2,r2][l_2,r_2][l2,r2]对应的位置染上同样的颜色(使得它们 ...
- JUC 一 Callable
java.util.concurrent.Callable是一个泛型接口,只有一个call()方法 Callable和Runnable的区别 Callable使用call()方法,Runnable使用 ...
- mysql插入数据显示:Incorrect datetime value: '0000-00-00 00:00:00'
1. 在进行mysql数据插入的时候,由于mysql的版本为5.7.1,部分功能已经升级,导致在datetime数据类型的影响下出现错误: 数据插入: mysql>insert into j ...
- Bitcoin 的基本原理
昨天读到了 Bitcoin 的中文介绍,觉得非常有意思.不过上面这篇文章解释的非常不靠谱,我花了一晚上去Bitcoin的官方网站 仔细研究了一下,总算理解了其原理.感觉非常有启发,尤其是对虚拟货币的流 ...
- Android之TableLayout表格布局
1.相关属性 1.1.常用属性 android:collapseColumns 设置需要被隐藏的列的序列号 android:shrinkColumns 设置允许被收缩的列的序列号 android:st ...