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

参考链接:

  完全理解 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/

  容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用innot 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. 004.ES2015和ES2016新特性--块级作用域变量

    其基本原理就是JavaScript的作用域链,下面以对比的方式来展示一下函数级作用域和块级作用域. 函数级作用域 var fns = []; for (var i = 0; i < 5 ; i+ ...

  2. 数组的常用方法 Array;

    数组: 1,arr.join();//返回默认由逗号隔开的一个字符串,传参则返回所传参数隔开的一个字符串; 2,arr.push();//往数组最后添加数据,返回新的数组的length,这个方法将改变 ...

  3. UVA-12083 Guardian of Decency 二分图 最大独立集

    题目链接:https://cn.vjudge.net/problem/UVA-12083 题意 学校组织去郊游,选择最多人数,使得任意两个人之间不能谈恋爱 不恋爱条件是高差大于40.同性.喜欢的音乐风 ...

  4. HDU-3416 Marriage Match IV 最短路+最大流 找各最短路的所有边

    题目链接:https://cn.vjudge.net/problem/HDU-3416 题意 给一个图,求AB间最短路的条数(每一条最短路没有重边.可有重复节点) 思路 首先把全部最短路的边找出来,再 ...

  5. 搭建rsync实时同步

    1.本实验基于centos6.5服务器做的 cat cat /etc/redhat-release 2.在配置环境之前需要先将服务器自带的rsync卸除 yum -y remove rsync* 3. ...

  6. ActiveMQ客户端配置使用

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

  7. [terry笔记]oracle里的执行计划-查看

    内容主要来自看书学习的笔记,如下记录了常见查询执行计划的方法. 2.2 如何查看执行计划 1.explain plan 2.dbms_xplan包 3.autotrace 4.10046事件 5.10 ...

  8. ZOJ 2601 Warehouse Keeper

    Warehouse Keeper Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on ZJU. Origin ...

  9. LibSVM C/C++

    本系列文章由 @YhL_Leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50179779 在LibSVM的库的sv ...

  10. 洛谷 P2926 [USACO08DEC]拍头Patting Heads

    P2926 [USACO08DEC]拍头Patting Heads 题目描述 It's Bessie's birthday and time for party games! Bessie has i ...