迭代器,生成器,yield,yield from理解
迭代器
说到迭代器就得想说可迭代对象Iterable,实现了__iter__()方法的对象都是可迭代对象,例如很多容器,list ,set, tuples。使用iter方法可以把一个可迭代对象变成迭代器
迭代器是实现了__next__()方法的可迭代对象,也就是说迭代器必须实现__iter__()和__next__()方法,迭代器可以调用next()放不断的迭代,在给定的范围中返回数据,超出范围抛出异常。
几个有趣的例子:
from itertools import count
counter = count(start=13)
next(counter)
13
next(counter)
14 无限序列只要你愿意可以一直迭代下去,然而你无法创建一个这么大的list是不是可以说的迭代器的优点呢
from itertools import cycle
colors = cycle(['red', 'white', 'blue'])
print next(colors)
# 'red'
print next(colors)
# 'white'
print next(colors)
# 'blue'
print next(colors)
# 'red' 无限循环序列
from itertools import islice,cycle
colors = cycle(['red', 'white', 'blue'])
limited = islice(colors, 0, 6)
for x in limited:
print(x)
#有限序列
from itertools import islice
class Fib:
def __init__(self):
self.prev = 0
self.curr = 1
def __iter__(self):
return self def __next__(self): #注意在python2中需要写成next() python3中写成__next__()
value = self.curr
self.curr += self.prev
self.prev = value
return value
f = Fib()
print(list(islice(f, 0, 10)))
生成器
简单的生成器(x for x in range(5)) 和列表生成式很像,如果生成的逻辑比较复杂,用类似列表生成式的方式难以表达,我们可以用函数加关键字yield的方式。
在我的理解中,生成器generator是一种特殊的迭代器,他用yield来自动实现了__iter__()和__next__()方法
那我们用yield来实现一下斐波拉契:
def fib():
prev = 0
curr = 1
while True:
value = curr
yield value
curr += prev
prev = value
a = fib()
for x in range(10):
print(next(a))
yield
这个yield这么神奇吗?到底该怎么理解它呢?首先你可以把它当成一个return,之后就不再继续往下执行了,调用next()方法后继续执行,举个例子。
def foo():
print("starting...")
while True:
res = yield 4
print("res:",res)
g = foo()
print(next(g))
print("*"*20)
print(next(g))
starting...
4 # 走到yield 4的时候马上return 4(马上返回并没有赋值操作),
********************
res: None #接着 yield 继续往下走,进行赋值操作,4已经被return 出去了,所以res=None
4 # 进入下一个循环,又走到yield 4
我们稍微修改一下函数
def foo():
print("starting...")
while True:
res = yield 4
print("res:",res)
g = foo()
print(next(g))
print("*"*20)
print(g.send(7))
starting...
4
********************
res: 7 #挺神奇的怎么变成7了,注意我们此时用的是send()方法,它是传递了一个值给yield表达式,相当于res=7
4
yield from
yield 是从生成器里返回一个元素,那么yield from 从名字上理解就应该是返回一个生成器咯
def foo():
yield from [1,2,3] a = foo()
print(next(a))
print(next(a))
print(next(a))
结果:
1
2
3
是不是就可以理解为yield from 返回的是 iter([1,2,3])呢
下面看两个例子
def foo():
for i in range(5):
if i == 2:
return 'gg'
else:
yield i
a = foo()
for i in a:
print(i)
0
1
def foo():
for i in range(5):
if i == 2:
return 'gg'
else:
yield i
a = foo()
for i in range(5):
print(next(a))
0
1
StopIteration: gg
这是yield的特性,在使用for循环取遍历生成器的时候是不会触发StopIteration异常,使用next()可以触发,如果我们又想用for循环遍历又想触发异常怎么弄,再封装一下
def foo():
for i in range(5):
if i == 2:
return 'gg'
else:
yield i def fun(generator):
res = yield from generator
print(res) a = foo()
b = fun(a)
for x in b:
print(x)
0
1
gg # 捕捉到了异常并且把return 的值给了yield from 表达式
迭代器,生成器,yield,yield from理解的更多相关文章
- 【Python】迭代器、生成器、yield单线程异步并发实现详解
转自http://blog.itpub.net/29018063/viewspace-2079767 大家在学习python开发时可能经常对迭代器.生成器.yield关键字用法有所疑惑,在这篇文章将从 ...
- python迭代器与生成器及yield
一.迭代器(itertor) 1.可迭代: 在Python中如果一个对象有__iter__()方法或__getitem__()方法,则称这个对象是可迭代的(iterable). 其中__iter__( ...
- day4 内置函数 迭代器&生成器 yield总结 三元运算 闭包
内置函数: 内置函数 # abs()返回一个数字的绝对值.如果给出复数,返回值就是该复数的模. b = -100 print(b) print(abs(b)) # all() 所有为真才为真,只要有一 ...
- python基础-8迭代器(iter)和生成器(yield)
一 生成器 从Python2.2起,生成器提供了一种简洁的方式帮助返回列表元素的函数来完成简单和有效的代码. 它基于yield指令,允许停止函数并立即返回结果.此函数保存其执行上下文,如果需要,可立即 ...
- Python中的生成器与yield
对于python中的yield有些疑惑,然后在StackOverflow上看到了一篇回答,所以搬运过来了,英文好的直接看原文吧. 可迭代对象 当你创建一个列表的时候,你可以一个接一个地读取其中的项.一 ...
- Python迭代和解析(5):搞懂生成器和yield机制
解析.迭代和生成系列文章:https://www.cnblogs.com/f-ck-need-u/p/9832640.html 何为生成器 生成器的wiki页:https://en.wikipedia ...
- PHP的生成器、yield和协程
虽然之前就接触了PHP的yield关键字和与之对应的生成器,但是一直没有场景去使用它,就一直没有对它上心的研究.不过公司的框架是基于php的协程实现,觉得有必要深入的瞅瞅了. 由于之前对于生成器接触不 ...
- 关于生成器---(yield)
生成器:是自定义的迭代器(自己用python代码写的迭代器),函数中见到yield的就是生成器 那么yield前后的变量又该怎么理解 看例子一 def counter(name): print('%s ...
- Python中生成器和yield语句的用法详解
Python中生成器和yield语句的用法详解 在开始课程之前,我要求学生们填写一份调查表,这个调查表反映了它们对Python中一些概念的理解情况.一些话题("if/else控制流" ...
随机推荐
- 常用css代码(scss mixin)
溢出显示省略号 参过参数可以只是单/多行. /** * 溢出省略号 * @param {Number} 行数 */ @mixin ellipsis($rowCount: 1) { @if $rowCo ...
- C++中的静态成员函数
1,问完成的需求: 1,统计在程序运行期间某个类的对象数目: 1,静态成员变量满足了这个需求: 2,保证程序的安全性(不能使用全局变量): 3,随时可以获取当前对象的数目: 1,有没有什么特别的地方或 ...
- 52.Product of Array Except Self(除过自身的数组乘积)
Level: Medium 题目描述: Given an array nums of n integers where n > 1, return an array output such ...
- 八、hibernate的查询(HQL)
HQL:Hibernate Query Language 提供更加丰富灵活.更为强大的查询能力 HQL更接近SQL语句查询语法 面向对象的查询 "from Children where ci ...
- windows自动关机(任务计划程序 + exe文件)
需求:windows系统自动关机 的需求: 相关工具:win10系统中,使用windows自带的任务计划程序 和 windows自带的关机 exe文件 完成此需求 exe文件位置:C:\Windows ...
- AtCoder Beginner Contest 131 F - Must Be Rectangular!
题意:给出二维平面的n个点坐标,定义一种操作:若恰好三个点能形成一个矩形(当然这个矩形会缺了一个点),那么就在图上添加这个缺的点,问在原图上最多能进行几次这样的操作. 解法:这题想了挺久没想到,一看题 ...
- TextView点击后背景颜色、文字颜色改变(转)
转自:http://blog.csdn.net/u013278940/article/details/51152655 TextView本没有点击效果,故为实现点击后文字颜色改变和背景改变,需要写se ...
- Java jvisualvm简要说明(转)
转自:http://blog.csdn.net/a19881029/article/details/8432368 jvisualvm能干什么:监控内存泄露,跟踪垃圾回收,执行时内存.cpu分析,线程 ...
- Windows下Redis安装+可视化工具Redis Desktop Manager使用
Redis是有名的NoSql数据库,一般Linux都会默认支持.但在Windows环境中,可能需要手动安装设置才能有效使用.这里就简单介绍一下Windows下Redis服务的安装方法,希望能够帮到你. ...
- C变量
C 变量 变量其实只不过是程序可操作的存储区的名称.C 中每个变量都有特定的类型,类型决定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上. 变量的名称可以由字母.数字和下 ...