迭代器,生成器,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控制流" ...
随机推荐
- HDU 1387 Team Queue( 单向链表 )
Team Queue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- 用u盘和iso镜像文件装win8.1系统
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/xyl295528322/article/details/37910939 原料: 1.老毛桃U盘启动 ...
- Java原理领悟-线程池(Executor)
线程池全面解析 什么是线程池? 很简单,简单看名字就知道是装有线程的池子,我们可以把要执行的多线程交给线程池来处理,和连接池的概念一样,通过维护一定数量的线程池来达到多个线程的复用. 线程池的好处 我 ...
- SpringMVC学习(7):格式化显示
在系列(6)中我们介绍了如何验证提交的数据的正确性,当数据验证通过后就会被我们保存起来.保存的数据会用于以后的展示,这才是保存的价值.那么在展示的时候如何按照要求显示?(比如:小数保留一定的位数,日期 ...
- ajax基本原理实现
function ajax(method,url,data,success){ try{ var xhr=new XMLHttpRequest(); }catch(e){ xhr=new Active ...
- python实现发送文本邮件
简单实现了python发送文本邮件 #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/4/25 17:09 # @Author ...
- 前端学习(三十一)canvas(笔记)
canvas 画布 画图.做动画.做游戏=========================================== canvas就是新标签 必须获取绘图 ...
- 转载 Struts2之------Action类中的get,set方法和execute方法的使用规范和使用流程(规范是没有理由的,必须遵守!!!)
1,Action中get,set方法的使用流程? 前台form中有一个<input type="text" name="username"/> 如果 ...
- Linux eth0, eth1, ..., eth%d 的生成【转】
转自:https://blog.csdn.net/xiruanliuwei/article/details/78765255 一直很好奇,Linux下的eth0, eth1,eth2等是如何生成的~ ...
- javaweb登录验证码的实现
第一种 第一步: JSP <li><input name="validCode" id="validCode" type="te ...