#最近一周刚开始接触python,基本的语法,和使用特性和Java差别还是蛮大的。

今天接触到Python的迭代器和生成器有点不是很明白,所以搜索了先关资料整理了一些自己的理解和心得

简述(Profile):

  迭代是Python最强大的功能之一,是访问集合元素的一种方式。

  Iteration one of Python's most powerful functions and a way to access colleaction elements.

  迭代器是一个可以记住遍历位置的对象

  An iterator is an object that can remenber to traverse the location.

  迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

  The Iterator onject starts from the first element of the collection until all the elements are accessed. The iterator can only move forward without going backwards.

  迭代器有两个基本的方法:iter() 和 next().

  Iterator have two basic methods: iter() and next()

  字符串,列表和元组对象都可用于创建迭代器:

  Strings, lists, and tuples can be used to create iterators:  

>>>list=[1,2,3,4]
>>> it = iter(list) # 创建迭代器对象
>>> print (next(it)) # 输出迭代器的下一个元素
1
>>> print (next(it))
2
>>>

实例(Instance)

  迭代器可以使用常规for语句进行遍历:

  Iterators can be traversed using the resular for statements:

#!/usr/bin/python3

list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
for x in it:
print (x, end=" ")

  执行以上程序,输出结果如下:

  The above procedures are performed and the output results are as follows:

1 2 3 4

生成器的背景:(Background Of Generator)

  通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

  With a list generation, we can create a list directly. However, with memory constraints, the list capacity is centainly limited. And create a list containing 1 million elements, not only takes up a lof of storage space, if we only need access to the front several elemts, that behind the vast majaority of the elements to take up the space is wasted.

  所以,如果列表可以通过某种算法算出来,那我们是否可以在循环的过程中不断地推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制称之为生成器(Generator)。

  So, if the list can be calculated by some algorithm, So can we constanly extrapolate the following elements in the loop? This saves a lot of space by not creating a complete list. In Python, the mechanism of this side loop is called a Generator.

  要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

  There are many ways to create a generator. The first method is simple, so if you change a list to (), you create a generator:  

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x104feab40>

  创建Lg的区别仅在于最外层的[]()L是一个list,而g是一个generator。

  The difference between creating L and g is only the outermost [] and (), L is a list, and g is a generator.

  如果要一个一个打印出来,可以通过generator的g.__next__()或者next(g)方法:(在Python2 中使用的是g.next()方法)

  If you want to print them one by one, you can use the g.__next() or next(g) mehod of generator:  

>>> g.__next__()
0
>>> g.__next__()
1
>>> g.__next__()
4
>>> g.__next__()
9
>>> g.__next__()
16
>>> g.__next__()
25
>>> g.__next__()
36
>>> g.__next__()
49
>>> g.__next__()
64
>>> g.__next__()
81
>>> g.__next__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

  generator保存的是算法,每次调用__next__(),就计算出下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

  The generator saves the algorithm, and each time it calls __next__(), it computes the value of the next element until the last element is calculated, and when there is no more elements, the error of StopIteration is thrown.

  generator 非常强大。如果推算的算法比较复杂,总类似列表生成式的for循环无法实现的时候,还可以用函数来实现。

  The generator is very powerful. If the calculated algorithm is more complex, the "for loop" of the list generation is not realized, and the function can be used to realize it.

  比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:

  For example, the famous Fibonacci sequence (Fibonacci), except for the first and second Numbers, any number can be added by the first two Numbers:

  1, 1, 2, 3, 5, 8, 13, 21, 34, ...

  斐波拉契数列用列表生成式写不出来,但是,用函数把它打印出来却很容易:

  The Fibonacci sequence can't be written out of the list, but it's easy to print it out with a function:  

def fib(max):
n, a, b = 0, 0, 1
while n < max:
print b
a, b = b, a + b
n = n + 1

  上面的函数可以输出斐波那契数列的前N个数:

  The above function can output the first N numbers of the Fibonacci sequence:  

>>> fib(6)
1
1
2
3
5
8

  仔细观察,可以看出,fib函数实际上是定义了斐波拉契数列的推算规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑其实非常类似generator。

   If you look closely, you can see  that fib is actually defines the Fibonacci ratched series calculations rules, can start on the first element, determine the subsequent arbitrary elements, this logic is very simialr to the generator.

  也就是说,上面的函数和generator仅一步之遥。要把fib函数的返回值变成generator,只需要把print b改为yield b就可以了:

  In other words, the above functions is just one step away from the generator. To turn the return value of the fib function into the generator, just change the 'print(b) to yield b.

def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b
a, b = b, a + b
n = n + 1

  这就是定义generator的另一种方法。如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,它的返回值就是是一个generator:

  This is another way to define the generator.  If a function definition contains the yield keyword, the function is no longer a normal function, and its return value is a generator.

  举个简单的例子,定义一个generator,依次返回数字1,3,5:

  For a simple example, define a generator and return the number 1,3,5:

>>> def odd():
... print 'step 1'
... yield 1
... print 'step 2'
... yield 3
... print 'step 3'
... yield 5
...
>>> o = odd()
>>> o.__next__()
step 1
1
>>> o.__next__()
step 2
3
>>> o.__next__()
step 3
5
>>> o.__next__()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

可以看到,odd不是普通函数,它的返回值是generator,在执行过程中,遇到yield就中断,下次又继续执行。执行3次yield后,已经没有yield可以执行了,所以,第4次调用next()就报错。

As you can see, odd is nor a normal function, and its return value is the generator. In the execution process, the yield is interrunpted and the next time it is executed. After  executing the yield three times, there no yield to be executed, so the forth call to next() is an error.

回到fib的例子,我们在循环过程中不断调用yield,就会不断中断。当然要给循环设置一个条件来退出循环,不然就会产生一个无限数列出来。

So back to the fib example, we're constanly calling the yield, and it's going to break. Of cause, you have to set a condition for the loop exit the loop, or you'll have a infinite number.

同样的,把函数改成generator后,我们基本上从来不会用next()来调用它,而是直接使用for循环来迭代:

Similarly, after changing the function to the generator, we basically never involke it with next(), but instead use the for loop to iterate:

>>> for n in fib(6):
... print n
...
1
1
2
3
5
8

Reference Documents: https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/00138681965108490cb4c13182e472f8d87830f13be6e88000

Python 生成器 Generator 和迭代器 Iterator的更多相关文章

  1. python生成器(generator)、迭代器(iterator)、可迭代对象(iterable)区别

    三者联系 迭代器(iterator)是一个更抽象的概念,任何对象,如果它的类有next方法(next python3)和__iter__方法返回自己本身,即为迭代器 通常生成器是通过调用一个或多个yi ...

  2. 生成器generator和迭代器Iterator

    一.列表生成式       在学习生成器迭代器之前先了解一下什么是列表生成式,列表生成式是Python内置的非常简单却强大的可以用来创建list的生成式.什么意思?举个例子,如果想生成列表[0,1,2 ...

  3. Python之生成器(generator)和迭代器(Iterator)

    generator 生成器generator:一边循环一边计算的机制. 生成器是一个特殊的程序,可以被用于控制循环的迭代行为.python中的生成器是迭代器的一种,使用yield返回值函数,每次调用y ...

  4. Python中生成器generator和迭代器Iterator的使用方法

    一.生成器 1. 生成器的定义 把所需要值得计算方法储存起来,不会先直接生成数值,而是等到什么时候使用什么时候生成,每次生成一个,减少计算机占用内存空间 2. 生成器的创建方式 第一种只要把一个列表生 ...

  5. 【python之路29】python生成器generator与迭代器

    一.python生成器 python生成器原理: 只要函数中存在yield,则函数就变为生成器函数 #!usr/bin/env python # -*- coding:utf-8 -*- def xr ...

  6. 学习python第十二天,函数4 生成器generator和迭代器Iterator

    在Python中,这种一边循环一边计算的机制,称为生成器:generator 要创建一个generator,有很多种方法.第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个genera ...

  7. Python 生成器 (generator) & 迭代器 (iterator)

    python 生成器 & 迭代器 生成器 (generator) 列表生成式 列表生成式用来生成一个列表,虽然写的是表达式,但是储存的是计算出来的结果,因此生成的列表受到内存大小的限制 示例: ...

  8. 【Python之路】特别篇--生成器(constructor)、迭代器(iterator)、可迭代对象(iterable)

    生成器(constructor) 生成器函数在Python中与迭代器协议的概念联系在一起.包含yield语句的函数会被特地编译成生成器 !!! 当函数被调用时,他们返回一个生成器对象,这个对象支持迭代 ...

  9. Python学习笔记014——迭代器 Iterator

    1 迭代器的定义 凡是能被next()函数调用并不断返回一个值的对象均称之为迭代器(Iterator) 2 迭代器的说明 Python中的Iterator对象表示的是一个数据流,被函数next()函数 ...

随机推荐

  1. FPGA初学之前后仿真分析

    最近在学习FPGA,感觉语言的学习到时很容易,但是由于缺乏电路图的硬件知识,所以看起来比较难懂,下面是对FPGA中仿真的一点理解,以后需要学习的地方还有很多啊. 一.使用ISE环境进行FPGA系统设计 ...

  2. (转载) Android开发时,那些相见恨晚的工具或网站!

    huangmindong的专栏       目录视图 摘要视图 订阅 赠书 | 异步2周年,技术图书免费选      程序员8月书讯      项目管理+代码托管+文档协作,开发更流畅 Android ...

  3. 【原创】JMS生产者和消费者【PTP异步接收消息】

    PTP模式下,异步接收消息需要定义一个MessageListener来监听,当生产者有消息要发送时会主动通知Listener去处理该消息,会调用监听的onMessage方法去处理. 首先看生产者(和同 ...

  4. ActiveMQ客户端配置使用

    一.通过JNDI来使用ActiveMQ 1.jndi配置JMS对象 java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQIni ...

  5. docker-ce-17.03.2 离线安装RPM包

    [root@docker05 docker]# ll total 20796 -rw-r--r-- 1 root root    75032 Mar 26 23:52 audit-libs-pytho ...

  6. 2016 10 27 考试 dp 向量 乱搞

    目录 20161027考试 T1: T2: T3: 20161027考试 考试时间 7:50 AM to 11:15 AM 题目 考试包 据说这是一套比较正常的考卷,,,嗯,,或许吧, 而且,,整个小 ...

  7. GBK编码具体解析(附GBK码位分布图)

    1.GBK码位分布图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA= ...

  8. POJ 2570 Fiber Network(最短路 二进制处理)

    题目翻译 一些公司决定搭建一个更快的网络.称为"光纤网". 他们已经在全世界建立了很多网站.这 些网站的作用类似于路由器.不幸的是,这些公司在关于网站之间的接线问题上存在争论,这样 ...

  9. cocos2d-x 粒子效果

    大规模运动的物体通常有两种方法实现 1.使用帧动画来模拟 2,粒子效果 粒子系统有CCParticleSystem类实现,CCParticleSystem实现了对粒子的控制与调度,对粒子的操作包含: ...

  10. HDU-3577-Fast Arrangement-区间更新

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3577 好吧,我认为这道题有必要说一下题目意思:毕竟我刚開始是没有看太懂,原谅我这个英语渣渣...ORZ ...