迭代器

说到迭代器就得想说可迭代对象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理解的更多相关文章

  1. 【Python】迭代器、生成器、yield单线程异步并发实现详解

    转自http://blog.itpub.net/29018063/viewspace-2079767 大家在学习python开发时可能经常对迭代器.生成器.yield关键字用法有所疑惑,在这篇文章将从 ...

  2. python迭代器与生成器及yield

    一.迭代器(itertor) 1.可迭代: 在Python中如果一个对象有__iter__()方法或__getitem__()方法,则称这个对象是可迭代的(iterable). 其中__iter__( ...

  3. day4 内置函数 迭代器&生成器 yield总结 三元运算 闭包

    内置函数: 内置函数 # abs()返回一个数字的绝对值.如果给出复数,返回值就是该复数的模. b = -100 print(b) print(abs(b)) # all() 所有为真才为真,只要有一 ...

  4. python基础-8迭代器(iter)和生成器(yield)

    一 生成器 从Python2.2起,生成器提供了一种简洁的方式帮助返回列表元素的函数来完成简单和有效的代码. 它基于yield指令,允许停止函数并立即返回结果.此函数保存其执行上下文,如果需要,可立即 ...

  5. Python中的生成器与yield

    对于python中的yield有些疑惑,然后在StackOverflow上看到了一篇回答,所以搬运过来了,英文好的直接看原文吧. 可迭代对象 当你创建一个列表的时候,你可以一个接一个地读取其中的项.一 ...

  6. Python迭代和解析(5):搞懂生成器和yield机制

    解析.迭代和生成系列文章:https://www.cnblogs.com/f-ck-need-u/p/9832640.html 何为生成器 生成器的wiki页:https://en.wikipedia ...

  7. PHP的生成器、yield和协程

    虽然之前就接触了PHP的yield关键字和与之对应的生成器,但是一直没有场景去使用它,就一直没有对它上心的研究.不过公司的框架是基于php的协程实现,觉得有必要深入的瞅瞅了. 由于之前对于生成器接触不 ...

  8. 关于生成器---(yield)

    生成器:是自定义的迭代器(自己用python代码写的迭代器),函数中见到yield的就是生成器 那么yield前后的变量又该怎么理解 看例子一 def counter(name): print('%s ...

  9. Python中生成器和yield语句的用法详解

    Python中生成器和yield语句的用法详解 在开始课程之前,我要求学生们填写一份调查表,这个调查表反映了它们对Python中一些概念的理解情况.一些话题("if/else控制流" ...

随机推荐

  1. IntelliJ IDEA 常用快捷键和技巧

    IntelliJ Idea 常用快捷键列表 Alt+回车 导入包,自动修正Ctrl+N  查找类Ctrl+Shift+N 查找文件Ctrl+Alt+L  格式化代码Ctrl+Alt+O 优化导入的类和 ...

  2. BUUCTF weirdlist 一路到底

    Weird list 这题恶心的一批 给了一堆列表 这...这是人做的题吗... 放飞自我,打开脑洞 把‘1’空出来,其他数字换为‘*’画出来 然后看到了flag,但是 这...这是什么flag,ag ...

  3. Bata冲刺第三天

    这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass2 这个作业要求在哪里 https://edu.cnblo ...

  4. opengl 库glew

    OpenGL OpenGL是个专业的3D程序接口,是一个功能强大,调用方便的底层3D图形库.OpenGL的前身是SGI公司为其图形工作站开发的IRIS GL.IRIS GL是一个工业标准的3D图形软件 ...

  5. 转帖 移动前端开发之viewport的深入理解

    在移动设备上进行网页的重构或开发,首先得搞明白的就是移动设备上的viewport了,只有明白了viewport的概念以及弄清楚了跟viewport有关的meta标签的使用,才能更好地让我们的网页适配或 ...

  6. oracle 数据库插入中文乱码

    一. 查询数据库编码 select userenv('language') from dual; 查询服务器编码 select * from v$nls_parameters; 推出sql查询系统编码 ...

  7. 【leetcode】996. Number of Squareful Arrays

    题目如下: Given an array A of non-negative integers, the array is squareful if for every pair of adjacen ...

  8. Windows最值得安装的小众软件

    用电脑这么久,也琢磨出自己的一些使用心得.今天和大家分享几个Windows效率工具.数量不多,但每个都是精品. ▌软件下载-卫星公众好「悦享软件」,在后台会话框中回复关键字:h108 1.Ditto ...

  9. VC2010 CString.Format使用报错 error C2664

    error C2664: “void ATL::CStringT<BaseType,StringTraits>::Format(const wchar_t *,...)”: 不能将参数 1 ...

  10. iconfont字体图标的使用方法

    转载于https://www.cnblogs.com/hjvsdr/p/6639649.html 我之前因为项目用bootstrap比较多,所以使用font awesome字体图标比较多,后来接触到了 ...