#最近一周刚开始接触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. 基于localStorage的登录注册

    以下代码,如果有地方有错,请直接指出,我会改进的(只改错误,不改逻辑,因为我自己是不会这样写代码的,这个只适合初学者): <!DOCTYPE html> <html> < ...

  2. HDU 1175 连连看【BFS】

    题意:给出起点和终点的棋子,不能经过别的棋子,而且转弯的次数不能超过2次,问能否消除 和逃离迷宫一样,每个节点记录下来它的当前的方向和转弯的次数,再搜 注意特判起点的棋子和终点的棋子为0或者不一样的情 ...

  3. swift语言点评十四-继承

    Overriding A subclass can provide its own custom implementation of an instance method, type method, ...

  4. 结构化数据、半结构化数据、非结构化数据——Hadoop处理非结构化数据

    刚开始接触Hadoop ,指南中说Hadoop处理非结构化数据,学习数据库的时候,老师总提结构化数据,就是一张二维表,那非结构化数据是什么呢?难道是文本那样的文件?经过上网搜索,感觉这个帖子不错 网址 ...

  5. 企业微信H5支付返回不到自己指定的结果页面

    项目:vue做的H5项目,嵌入到企业微信里 发现的问题:支付完成后的跳转页面 跳转不到自己指定的页面 问题在于:调支付接口时,redirectUrl: document.location.protoc ...

  6. 简洁的MVC思想框架——Nancy(环境配置与Get操作)

    Nancy官网——https://github.com/NancyFx/Nancy 概述:Nancy是一个开源的Web轻型框架内核符合MVC思想,有开发方便,路由简单的特点,而且功能齐全 起步:Hel ...

  7. UVA-1347 Tour 动态规划 难以确定的状态

    题目链接:https://cn.vjudge.net/problem/UVA-1347 题意 给出按x坐标排序的几个点. 欲从最左边不回头的走到最右边,然后再返回最左边. 每个点都要被访问,且只能经过 ...

  8. [NOIP2011提高组]Mayan游戏

    题目:洛谷P1312.Vijos P1738.codevs1136. 题目大意:在一个7行5列的棋盘(左下角坐标0,0)上,有一些不同颜色的棋子. 规定某一时刻,连续三个横排或竖列的棋子颜色相同,则它 ...

  9. list 分页

    package com.jsz.peini.common.util; import java.util.ArrayList; import java.util.List; public class S ...

  10. 改造vue-quill-editor: 结合element-ui上传图片到服务器

    前排提示:现在可以直接使用封装好的插件vue-quill-editor-upload 需求概述 vue-quill-editor是我们再使用vue框架的时候常用的一个富文本编辑器,在进行富文本编辑的时 ...