我刚开始学习编程没多久,对于很多知识还完全不知道,而有些知道的也是一知半解,我想把学习到的知识记录下来,一是弥补记忆力差的毛病,二也是为了待以后知识能进一步理解透彻时再回来做一个补充。

参考链接:

  完全理解 Python 迭代对象、迭代器、生成器:http://python.jobbole.com/87805/

一、迭代器(iterator)

  参考链接:http://www.runoob.com/python3/python3-iterator-generator.html

  迭代是Python最强大的功能之一,是访问集合元素的一种方式。迭代器是一个对象,是一个可以记住遍历位置的对象,或者说是一个带状态的对象,他能在你调用 next() 方法的时候返回容器中的下一个值,(我的理解是这个状态与next有关,代表当前处于哪个位置)

  迭代器对象(把人比作迭代器,那么迭代器对象就是小明,不要笑,要不本人理解不清楚)从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

  迭代器就像一个懒加载的工厂,等到有人需要的时候才给它生成值返回,没调用的时候就处于休眠状态等待下一次调用。

  创建迭代器对象:

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

>>>list=[1,2,3,4]
>>> it = iter(list) # 创建迭代器对象

  迭代器有两个基本的方法:iter() 和 next(),可以使用next或者for循环进行遍历

  创建一个迭代器:(不是迭代器对象)

  把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__() 。

  如果你已经了解的面向对象编程,就知道类都有一个构造函数,Python 的构造函数为 __init__(), 它会在对象初始化的时候自动调用。

  __iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并通过 StopIteration 异常标识迭代的完成。

  __next__() 方法(Python 2 里是 next())会返回下一个迭代器对象。

  StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,在 __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常使用 raise 语句来结束迭代。

  迭代器持有一个内部状态的字段,用于记录下次迭代返回值,它实现了__next__和__iter__方法(我的理解是迭代器是一个称号,就像英语证书一样,你通过考试(这里是实现两个功能即)才能拿到证书),迭代器不会一次性把所有元素加载到内存,而是需要的时候才生成返回结果。

  

二、可迭代对象iterable

  iterable--是在学习yield语句时看到一篇博客了解到的:http://www.runoob.com/w3cnote/python-yield-used-analysis.html

  作者写的非常好,为了让读者更透彻的理解yield语句的功能和特点,他循序渐进的对一个程序进行了多次改进,有一小节就提到了iterable。经过初步的学习,我还没有理解这是个啥?甚至连它是一个数据类型还是方法都没搞清楚,不管这样,先把学习到的知识记录下来吧!待以后再慢慢理解

  但凡是可以返回一个迭代器的对象都可称之为可迭代对象,可迭代对象和容器一样是一种通俗的叫法,并不是指某种具体的数据类型

  具有 iterable 类型的集合可以通过新的 for ... of 循环来遍历。

   for ... of 好像是JavaScript语言里面的

   for ... in 循环由于历史遗留问题,它遍历的实际上是对象的属性名称。一个 Array 数组实际上也是一个对象,它的每个元素的索引被视为一个属性。

  当我们手动给 Array 对象添加了额外的属性后, for ... in 循环将带来意想不到的意外效果:

var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x in a) {
console.log(x); // '0', '1', '2', 'name'
}

  

   for ... in 循环将把 name 包括在内,但 Array 的 length 属性却不包括在内。

   for ... of 循环则完全修复了这些问题,它只循环集合本身的元素:

var a = ['A', 'B', 'C'];
a.name = 'Hello';
for (var x of a) {
console.log(x); // 'A', 'B', 'C'
}

  然而,更好的方式是直接使用 iterable 内置的 forEach 方法,它接收一个函数,每次迭代就自动回调该函数。以 Array 为例:

'use strict';
var a = ['A', 'B', 'C'];
a.forEach(function (element, index, array) {#每次迭代就回调function
// element: 指向当前元素的值
// index: 指向当前索引
// array: 指向Array对象本身
console.log(element + ', index = ' + index);
});
#输出
A, index = 0
B, index = 1
C, index = 2

  Map和Set的回调函数的参数见链接:https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/00143450082788640f82a480be8481a8ce8272951a40970000

三、生成器generator

  yield语句

  在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

  yield语句使用:http://www.runoob.com/w3cnote/python-yield-used-analysis.html(先看结论)

  参考链接:https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/00138681965108490cb4c13182e472f8d87830f13be6e88000

  把python中一边循环一边按照规律计算下一个的机制叫做生成器

  生成器是一个返回迭代器的函数

  创建生成器的两个办法:一个是列表生成式、一个是将使用yield语句将函数变成生成器

  列表生成式方法:

  用来解决一个较大的列表却每次只使用其中一个元素造成内存浪费的问题

  用函数来实现生成器:

  如果推算的算法比较复杂,类似列表生成式的for循环无法实现的时候,还可以用函数来实现。如果一个函数定义中包含 yield 关键字,那么这个函数就不再是一个普通函数,而是一个generator。

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

  例子见链接

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

  这里,最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用 next() 的时候执行,遇到 yield (while True语句是也是这个意思,我刚开始没有拐过来弯)语句返回,再次执行时从上次返回的 yield 语句处继续执行。

  我把它理解为使用 next() 来调用生成器(看成是一次计算),但更好的办法是通过for循环来进行迭代

  generator是非常强大的工具,在Python中,可以简单地把列表生成式改成generator,也可以通过函数实现复杂逻辑的generator。

  生成器是一种特殊的迭代器,它的返回值不是通过 return 而是用 yield 。

  要理解generator的工作原理,它是在 for 循环的过程中不断计算出下一个元素,并在适当的条件结束 for 循环。对于函数改成的generator来说,遇到return语句或者执行到函数体最后一行语句,就是结束generator的指令, for 循环随之结束。

四、容器

  参考链接:http://python.jobbole.com/87805/

  容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in, not in关键字判断元素是否包含在容器中。容器比较容易理解,因为你就可以把它看作是一个盒子、一栋房子、一个柜子,里面可以塞任何东西。从技术角度来说,当它可以用来询问某个元素是否包含在其中时,那么这个对象就可以认为是一个容器,比如 list,set,tuples都是容器对象

  尽管绝大多数容器都提供了某种方式来获取其中的每一个元素,但这并不是容器本身提供的能力,而是可迭代对象赋予了容器这种能力

五、xrange和range的区别

  参考链接:http://ciniao.me/article.php?id=17

  只有在python2中有区别,python3中没有了

  xrange生成的不是一个数组,而是一个生成器(关于生成器我也不清楚,猜测是只有使用时才会生成)

>>> xrange(5)
xrange(5)
>>> list(xrange(5))
[0, 1, 2, 3, 4]
>>> xrange(1,5)
xrange(1, 5)#不立即生成,只有使用时会生成
>>> list(xrange(1,5))
[1, 2, 3, 4]
>>> xrange(0,6,2)
xrange(0, 6, 2)
>>> list(xrange(0,6,2))
[0, 2, 4]

  range会直接生成一个列表,而xrange不是这样,只在每次调用时返回一个值,所以要生成很大的数字序列的时候,用xrange会比range性能优很多,因为不需要一上来就开辟一块很大的内存空间。

python -迭代器与生成器 以及 iterable(可迭代对象)、yield语句的更多相关文章

  1. python迭代器和生成器(3元运算,列表生成式,生成器表达式,生成器函数)

    1.1迭代器 什么是迭代器: 迭代器是一个可以记住遍历的位置对象 迭代器对象从集合的第一个元素元素开始访问,直到所有元素被访问完结束,迭代器只能往前不会后退. 迭代器有两个基本方法:iter ,nex ...

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

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

  3. python 迭代器,生成器

    在 python 中我们常用 for in 来遍历 list, set, dict, str 等. for in 的本质就干了两件事: 调用 __iter__() 获取迭代器; 调用 next() 直 ...

  4. Python 迭代器和生成器(转)

    Python 迭代器和生成器 在Python中,很多对象都是可以通过for语句来直接遍历的,例如list.string.dict等等,这些对象都可以被称为可迭代对象.至于说哪些对象是可以被迭代访问的, ...

  5. python迭代器与生成器(二)

      一.什么是迭代? 迭代通俗的讲就是一个遍历重复的过程. 维基百科中 迭代(Iteration) 的一个通用概念是:重复某个过程的行为,这个过程中的每次重复称为一次迭代.具体对应到Python编程中 ...

  6. 8、如何实现可迭代对象和迭代器对象 9、如何使用生成器函数实现可迭代对象 10、如何进行反向迭代以及如何实现反向迭代 11、如何对迭代器做切片操作 12、如何在一个for语句中迭代多个可迭代对象

    8.如何实现可迭代对象和迭代器对象 PS:注意重载Iterator方法的时候,需要和原来的方法名一样,否则创建实例时会报错 from collections import Iterator,Itera ...

  7. Python之路【第六篇】:Python迭代器、生成器、面向过程编程

    阅读目录 一.迭代器 1.迭代的概念 #迭代器即迭代的工具,那什么是迭代呢? #迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 代码如下: while True: ...

  8. python 迭代器、生成器、枚举的使用

    迭代器 器:包含了多个值的容器 迭代:循环反馈(一次从容器中取出一个值) 迭代器:从装有多个值的容器中一次取出一个值给外界 遍历:被遍历的对象必须是有序容器 ls = [1, 2, 3, 4, 5] ...

  9. python基础一 ------利用生成器生成一个可迭代对象

    #利用生成器生成一个可迭代对象#需求:生成可迭代对象,输出指定范围内的素数,利用生成器产生一个可迭代对象#生成器:本身是可迭代的,只是 yield 好比return返回,yield返回后函数冻结状态, ...

随机推荐

  1. java 后台实现ajax post跨域请求传递json格式数据获取json数据问题

    参考大神:http://blog.csdn.net/chunqiuwei/article/details/19924821 java后台: public String ajaxProxy(Intege ...

  2. Analysis of the Facebook.app for iOS

    Analysis of the Facebook.app for iOS Posted Oct 18, 2016 Did you ever wonder why the Facebook.app fo ...

  3. JS 判断中英文字符长度

    function strlen(str) {        var len = 0;        for (var i = 0; i < str.length; i++) {          ...

  4. 转:EL表达式

    简介: EL 全名为 Language ,JSP2.0 之后,EL 成为了标准规范.因此,只要是支持Servlet2.4/JSP2.0 的容器,就都可以在JSP 网页中直接使用EL . 除了JSP2. ...

  5. POJ 3067 Japan 【 树状数组 】

    题意:左边有n个城市,右边有m个城市,现在修k条路,问会形成多少个交点 先按照x从小到大排,x相同的话,则按照y从小到大排,然后对于每一个y统计前面有多少个y比它大,它们就一定会相交 另外要用long ...

  6. split方法切割数组

    指定的字符串按"o"截取 当一个base64需要剪去前面的部分的时候 var params={ "imgJustBase64":this.zheng.split ...

  7. 紫书 习题 11-12 UVa 1665 (并查集维护联通分量)

    这道题要逆向思维 反过来从大到小枚举, 就是在矩阵中一点一点加进去数字,这样比较 好操作, 如果正着做就要一点一点删除数字, 不好做. 我们需要在这个过程中维护联通块的个数, 这里用到了并查集. 首先 ...

  8. SpringBoot实战(一)HelloWorld

    一:环境准备: JDK:1.8版本 Maven:3.5版本(如果觉得下载速度慢,可以切换为阿里镜向地址) Intellij:2018.2.1版本 二:实际操作: 1.在Intellij中创建一个新的S ...

  9. Opencv 三对角线矩阵(Tridiagonal Matrix)解法之(Thomas Algorithm)

    1. 简介 三对角线矩阵(Tridiagonal Matrix),结构如公式(1)所示: aixi−1+bixi+cixx+1=di(1) 其中a1=0,cn=0.写成矩阵形式如(2): ⎡⎣⎢⎢⎢⎢ ...

  10. 低价购买 洛谷1108 codevs4748 dp

    首先,,我相信第一问是可以做出来的,,,做不出来自行面壁思过,,, 第二问,我们可以发现,如果f[i]为1时应该将其g[i]初始化为1,当初就是因为这个wa了一个世纪,之后先考虑不需要判重时的情况,如 ...