迭代器,生成器,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控制流" ...
随机推荐
- python-form表单
form表单 form属于块级标签 功能: 表单用于向服务器传输数据,从而实现用户与web服务器的交互 表单能够包含input系列标签,比如文本字段.复选框.单选框.提交按钮等等 表单还可以包含tex ...
- 转 linux 服务器内存占用统计
linux 服务器内存占用统计 原文: https://www.cnblogs.com/eaglediao/p/6641811.html 当前内存占用率的计算,是根据top命令显示的Mem.used ...
- golang的数据类型之字符串类型
基本案例: [root@node3 shangxuetang]# cat string.go package main import "fmt" func main() { //s ...
- python字符串方法学习笔记
# 一.字符串大小写转换# 字符串首字符大写print("hello world".capitalize())# 将字符串变为标题print("hello WORLD&q ...
- Linux将动态IP改为静态IP
1.编辑 ifcfg-eth0 文件,vim 最小化安装时没有被安装,需要自行安装不描述. 2.修改如下内容 BOOTPROTO="static" #dhcp改为static ON ...
- awk 起始位置和长度和 mf 一致
1位开始 , 925开始 截取24 awk '{OFS="";print(substr($0,925,24),substr($0,1,24),substr($0,436,1),&q ...
- 【记录】Idea "Cannot resolve symbol 'SpringBootApplication'" 错误&“找不到主类”错误
初学,有一个Spring Boot的demo需要用Idea打开.我选择导入(Import Project选项)文件,出现如题错误,且yml文件格式也不正确显示(叶子). 后面细看目录,发现一个main ...
- oracle 数据恢复
闪回表删除之前 flashback table t1 to before drop; 如果彻底删除表此方法无效 若要彻底删除表,则使用语句:drop table <table_name> ...
- Qt 【widget如何铺满窗口】
刚接触qt不是很长时间,都是使用ui拖拽控件实现界面,然后发现有些问题就是控件一旦多了起来,拖拽就不好控制了,然后就转而使用纯代码开发. 一下是碰到第一个问题: 创建一个MainWidget; Mai ...
- Vue项目中导入excel文件读取成js数组
1. 安装组件 cnpm install xlsx --save 2. 代码 <template> <span> <input class="input-fil ...