python 迭代
迭代
循环(loop),指的是在满足条件的情况下,重复执行同一段代码。比如,while语句。
迭代(iterate),指的是按照某种顺序逐个访问列表中的每一项。比如,for语句。
递归(recursion),指的是一个函数不断调用自身的行为。比如,以编程方式输出著名的斐波纳契数列。
遍历(traversal),指的是按照一定的规则访问树形结构中的每个节点,而且每个节点都只访问一次。
对于这四个听起来高深莫测的词汇,在教程中,已经涉及到了一个——循环(loop),本经主要介绍一下迭代(iterate),看官在网上google,就会发现,对于迭代和循环、递归之间的比较的文章不少,分别从不同角度将它们进行了对比。这里暂不比较,先搞明白python中的迭代。
逐个访问
在python中,访问对象中每个元素,可以这么做:(例如一个list)
>>> lst ['h', 'i', 'e', 'k', 'a', 'y'] >>> for i in lst: ... print i, ... h i e k a y 除了这种方法,还可以这样: >>> lst_iter = iter(lst) #对原来的list实施了一个iter() >>> lst_iter.next() #要不厌其烦地一个一个手动访问 'h' >>> lst_iter.next() 'i' >>> lst_iter.next() 'y' >>> lst_iter.next() 'k' >>> lst_iter.next() 'a' >>> lst_iter.next() 'y' >>> lst_iter.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
循环:
>>> while True: ... print lst_iter.next() ... Traceback (most recent call last): #居然报错,而且错误跟前面一样?什么原因 File "<stdin>", line 2, in <module> StopIteration >>> lst_iter = iter(lst) #那就再写一遍,上面的错误暂且搁置,回头在研究 >>> while True: ... print lst_iter.next() ... h #果然自动化地读取了 i e k a y Traceback (most recent call last): #读取到最后一个之后,报错,停止循环 File "<stdin>", line 2, in <module> StopIteration >>>
首先了解一下上面用到的那个内置函数:iter(),官方文档中有这样一段话描述之:
iter(o[, sentinel])
Return an iterator object. The first argument is interpreted very differently depending on the presence of the second argument. Without a second argument, o must be a collection object which supports the iteration protocol (the iter() method), or it must support the sequence protocol (the getitem() method with integer arguments starting at 0). If it does not support either of those protocols, TypeError is raised. If the second argument, sentinel, is given, then o must be a callable object. The iterator created in this case will call o with no arguments for each call to its next() method; if the value returned is equal to sentinel, StopIteration will be raised, otherwise the value will be returned.
返回值是一个迭代器对象
参数需要是一个符合迭代协议的对象或者是一个序列对象
next()配合与之使用
什么是“可迭代的对象”呢?一般,我们常常将哪些能够用for来一个一个读取元素的对象,就称之为可迭代的对象。那么for也就被称之为迭代工具。所谓迭代工具,就是能够按照一定顺序扫描迭代对象的每个元素(按照从左到右的顺序),显然,除了for之外,还有别的可以称作迭代工具,比如列表解析,in来判断某元素是否属于序列对象等。
那么,刚才介绍的iter()的功能呢?它与next()配合使用,也是实现上述迭代工具的作用。在python中,甚至在其它的语言中,迭代这块的说法比较乱,主要是名词乱,刚才我们说,那些能够实现迭代的东西,称之为迭代工具,就是这些迭代工具,不少程序员都喜欢叫做迭代器。当然,这都是汉语翻译,英语就是iterator。
上面的所有例子会发现,如果用for来迭代,当到末尾的时候,就自动结束了,不会报错。如果用iter()...next()迭代,当最后一个完成之后,它不会自动结束,还要向下继续,但是后面没有元素了,于是就报一个称之为StopIteration的错误(这个错误的名字叫做:停止迭代,这哪里是报错,分明是警告)。
看官还要关注iter()...next()迭代的一个特点。当迭代对象lst_iter被迭代结束,即每个元素都读取一边之后,指针就移动到了最后一个元素的后面。如果再访问,指针并没有自动返回到首位置,而是仍然停留在末位置,所以报StopIteration,想要再开始,需要重新再入迭代对象。所以,列位就看到,当我在上面重新进行迭代对象赋值之后,又可以继续了。这在for等类型的迭代工具中是没有的。
文件迭代器
现在有一个文件,名称:iterfile.txt,其内容如下:
Learn python with hiekay.
There is free python course.
The website is:
http://hiekay.github.io
Its language is Chinese.
用迭代器来操作这个文件,我们在前面讲述文件有关知识的时候已经做过了,无非就是:
>>> f = open("iterfile.txt") >>> f.readline() #读第一行 'Learn python with hiekay.\n' >>> f.readline() #读第二行 'There is free python course.\n' >>> f.readline() #读第三行 'The website is:\n' >>> f.readline() #读第四行 'http://hiekay.github.io\n' >>> f.readline() #读第五行,也就是这真在读完最后一行之后,到了此行的后面 'Its language is Chinese.\n' >>> f.readline() #无内容了,但是不报错,返回空。 ''
以上演示的是用readline()一行一行地读。当然,在实际操作中,我们是绝对不能这样做的,一定要让它自动进行,比较常用的方法是:
>>> for line in f: #这个操作是紧接着上面的操作进行的,请看官主要观察 ... print line, #没有打印出任何东西 ...
这段代码之所没有打印出东西来,是因为经过前面的迭代,指针已经移到了最后了。这就是迭代的一个特点,要小心指针的位置。
>>> f = open("iterfile.txt") #从头再来 >>> for line in f: ... print line, ... Learn python with hiekay. There is free python course. The website is: http://hiekay.github.io Its language is Chinese.
这种方法是读取文件常用的。另外一个readlines()也可以。
上面过程用next()也能够读取。
>>> f = open("iterfile.txt") >>> f.next() 'Learn python with hiekay.\n' >>> f.next() 'There is free python course.\n' >>> f.next() 'The website is:\n' >>> f.next() 'http://hiekay.github.io\n' >>> f.next() 'Its language is Chinese.\n' >>> f.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
如果用next(),就可以直接读取每行的内容。这说明文件是天然的可迭代对象,不需要用iter()转换了。
再有,我们用for来实现迭代,在本质上,就是自动调用next(),只不过这个工作,已经让for偷偷地替我们干了。
前面提到了,列表解析也能够做为迭代工具,在研究列表的时候,看官想必已经清楚了。那么对文件,是否可以用?试一试:
>>> [ line for line in open('iterfile.txt') ] ['Learn python with hiekay.\n', 'There is free python course.\n', 'The website is:\n', 'http://hiekay.github.io\n', 'Its language is Chinese.\n']
至此, 列表解析 真的很强大。
其实,迭代器远远不止上述这么简单,下面我们随便列举一些,在python中还可以这样得到迭代对象中的元素。
>>> list(open('iterfile.txt')) ['Learn python with hiekay.\n', 'There is free python course.\n', 'The website is:\n', 'http://hiekay.github.io\n', 'Its language is Chinese.\n'] >>> tuple(open('iterfile.txt')) ('Learn python with hiekay.\n', 'There is free python course.\n', 'The website is:\n', 'http://hiekay.github.io\n', 'Its language is Chinese.\n') >>> "$$$".join(open('iterfile.txt')) 'Learn python with hiekay.\n$$$There is free python course.\n$$$The website is:\n$$$http://hiekay.github.io\n$$$Its language is Chinese.\n' >>> a,b,c,d,e = open("iterfile.txt") >>> a 'Learn python with hiekay.\n' >>> b 'There is free python course.\n' >>> c 'The website is:\n' >>> d 'http://hiekay.github.io\n' >>> e 'Its language is Chinese.\n'
上述方式,在编程实践中不一定用得上 。
补充一下,字典也可以迭代,可以自己不妨摸索一下(其实前面已经用for迭代过了,这次请摸索一下用iter()...next()手动一步一步迭代)。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
教程 | Tensorflow keras 极简神经网络构建与使用
Tensorflow keras极简神经网络构建教程 Keras介绍Keras (κέρας) 在希腊语中意为号角,它来自古希腊和拉丁文学中的一个文学形象。发布于2015年,是一套高级API框架,其默认的backend是tensorflow,但是可以支持CNTK、Theano、MXNet作为backend运行。其特点是语法简单,容易上手,提供了大量的实验数据接口与预训练网络接口,最初是谷歌的一位工程师开发的,非常适合快速开发。Tensorflow虽然是非常流行的深度学习框架,但是tensorflow开发需要了解计算图与自动微分相关技术,对于完全没有任何深度学习基础的人不是一个很好的选择,而keras完全是为零基础的人准备,它简化了tensorflow中计算图、会话等基本概念,通过Sequential与功能API两个组件实现网络搭建,通过简单的添加一些层就可以快速搭建神经网络模型。 Mnist数据集准备我们以mnist数据集为例,构建一个神经网络实现手写数字的训练与测试,首先我们需要认识一下mnist数据集,mnist数据集有6万张手写图像,1万张测试图像。Keras通过datase来下...
- 下一篇
Java-InnerClass内部类
成员内部类 成员内部类可以访问外部类的所有成员属性和成员方法(包括private成员和静态成员) 当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:外部类.this.成员变量,外部类.this.成员方法 成员内部类可以用private、protected、public修饰 成员内部类中不能定义静态方法(所以成员内部类中没有main方法) 成员内部类不能定义静态变量,静态方法 成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象 在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问 可以定义成员抽象内部类,抽象内部类的抽象方法不能用private、final、static修饰 静态内部类 静态内部类只能调用外部类的静态方法和静态属性 静态内部类不用产生外部类的实例化对象即可产生内部类的实例化对象 静态内部类也可以用private、protected、public修饰 静态内部类可以定义非...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS8安装Docker,最新的服务器搭配容器使用
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- 设置Eclipse缩进为4个空格,增强代码规范
- Red5直播服务器,属于Java语言的直播服务器
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS7安装Docker,走上虚拟化容器引擎之路