Python 生成器 Generator 和迭代器 Iterator
#最近一周刚开始接触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>
创建L
和g
的区别仅在于最外层的[]
和()
,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的更多相关文章
- python生成器(generator)、迭代器(iterator)、可迭代对象(iterable)区别
三者联系 迭代器(iterator)是一个更抽象的概念,任何对象,如果它的类有next方法(next python3)和__iter__方法返回自己本身,即为迭代器 通常生成器是通过调用一个或多个yi ...
- 生成器generator和迭代器Iterator
一.列表生成式 在学习生成器迭代器之前先了解一下什么是列表生成式,列表生成式是Python内置的非常简单却强大的可以用来创建list的生成式.什么意思?举个例子,如果想生成列表[0,1,2 ...
- Python之生成器(generator)和迭代器(Iterator)
generator 生成器generator:一边循环一边计算的机制. 生成器是一个特殊的程序,可以被用于控制循环的迭代行为.python中的生成器是迭代器的一种,使用yield返回值函数,每次调用y ...
- Python中生成器generator和迭代器Iterator的使用方法
一.生成器 1. 生成器的定义 把所需要值得计算方法储存起来,不会先直接生成数值,而是等到什么时候使用什么时候生成,每次生成一个,减少计算机占用内存空间 2. 生成器的创建方式 第一种只要把一个列表生 ...
- 【python之路29】python生成器generator与迭代器
一.python生成器 python生成器原理: 只要函数中存在yield,则函数就变为生成器函数 #!usr/bin/env python # -*- coding:utf-8 -*- def xr ...
- 学习python第十二天,函数4 生成器generator和迭代器Iterator
在Python中,这种一边循环一边计算的机制,称为生成器:generator 要创建一个generator,有很多种方法.第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个genera ...
- Python 生成器 (generator) & 迭代器 (iterator)
python 生成器 & 迭代器 生成器 (generator) 列表生成式 列表生成式用来生成一个列表,虽然写的是表达式,但是储存的是计算出来的结果,因此生成的列表受到内存大小的限制 示例: ...
- 【Python之路】特别篇--生成器(constructor)、迭代器(iterator)、可迭代对象(iterable)
生成器(constructor) 生成器函数在Python中与迭代器协议的概念联系在一起.包含yield语句的函数会被特地编译成生成器 !!! 当函数被调用时,他们返回一个生成器对象,这个对象支持迭代 ...
- Python学习笔记014——迭代器 Iterator
1 迭代器的定义 凡是能被next()函数调用并不断返回一个值的对象均称之为迭代器(Iterator) 2 迭代器的说明 Python中的Iterator对象表示的是一个数据流,被函数next()函数 ...
随机推荐
- png库结合zlib库使用出现的一个链接问题的解决
作者:朱金灿 来源:http://blog.csdn.net/clever101 要使用png库,首先得编译png库,要编译png库,得依赖zlib库的头文件.在使用png库读取一个png文件时,代码 ...
- 51nod 1158 全是1的最大子矩阵(单调栈 ,o(n*m))
前置问题:51nod 1102 面积最大的矩形 附上链接: 51nod 1102 面积最大的矩形 这题的题解博客 需要了解的知识:单调栈,在前置问题中已经讲解. 解题思路 对每行求左边连续1的个数,得 ...
- HDU 5234 Happy birthday【DP】
题意:给出n*m的格子,每个格子的值为w[i][j],在值不超过k的时候,可以往右或者往下走,问从(1,1)走到(n,m)能够得到的最大的值 类似于背包 d[i][j][k]=maxx(d[i-1][ ...
- xml中单词下面有提示下划线
xml中单词下面有提示下划线,表示单词拼写错误或者大小写错误
- django框架-DRF工程之权限功能
1.相对于flask,原生而言django,DRF做的则更加的合理化,想要给予用户相应的权限,首先需要在settings中进行配置 REST_FRAMEWORK = { 'DEAFAULT_PERMI ...
- BZOJ 1195 [HNOI2006]最短母串 (Trie图+状压+bfs最短路)
BZOJ1195 LOJ10061 题目大意:给你$n$个模式串,求一个最短且字典序最小的文本串并输出这个串,$n<=12,len<=50$ 首先对所有模式串构造$Trie$图,$Trie ...
- 二叉排序树(B-Tree)-c实现
这个二叉排序树写完了,虽然还有些bug,但还是很高兴的. 主要实现二叉排序树的构建.(*表示稍微重要点) 二叉排序树的打印. 二叉排序树的删除. 代码里的三种情况都测了 顺便附送一个简单的中序遍历,递 ...
- Linux CentOs6.5误卸载自带python和yum后的解决办法
事故背景:前几天因项目需要,在服务器上搭建python-mysql模块,结果没安装好,于是乎想卸载重装,遂在网上查询卸载python的方法,结果一不小心直接把系统的python删了个干净....... ...
- 洛谷 P1990 覆盖墙壁
P1990 覆盖墙壁 题目描述 你有一个长为N宽为2的墙壁,给你两种砖头:一个长2宽1,另一个是L型覆盖3个单元的砖头.如下图: 0 0 0 00 砖头可以旋转,两种砖头可以无限制提供.你的任务是计算 ...
- hdoj--1408--盐水的故事(技巧)
盐水的故事 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Subm ...