零基础学习 Python 之初识迭代

写在之前

大家好,这里是零基础学习 Python 系列,在这里我将从最基本的Python 写起,然后再慢慢涉及到高阶以及具体应用方面。我是完全自学的 Python,所以很是明白自学对于一个人的考验,所以在这里我会尽我最大的努力,把 Python 尽可能简单的表述清楚,让更多想要学习 Python 的朋友能够入门。同时写这个教程也算是对自己之前所学知识的一个巩固和提高,喜欢的朋友们可以点个关注,有问题欢迎随时和我交流。本文所有的代码编写均是Python3 版本。

在前面的文章中很多次的提到「迭代」 这个词,但是一直没有专门去写它,那么今天终于把它排上号了。当然了,迭代的这个话题要真的认真说起来的话会很多,本着循序渐进的原则,本篇文章先介绍比较初级的。

准备

在学习迭代之前,我们先来搞清楚下面这些名词:

1.循环(loop)

循环是指在满足条件的情况下,重复执行同一段代码,比如我们之前学过的 while 语句,忘记的请看这篇文章 — 零基础学习 Python 之 while 循环语句

2.迭代(Iterate)

迭代是指按照某种顺序逐个访问对象中的每一项,比如我们之前学过的 for 语句,忘记的请看这篇文章 — 零基础学习 Python 之 for 循环语句

3.递归(recursion)

递归是指一个函数不断调用自身的行为,比如我们很熟悉的斐波那契数列,如果不熟悉请自行搜索,很简单的。

4.遍历(traversal)

遍历是指按照一定的规则访问树形结构中的每个节点,而且每个节点都只访问一次,其实 for 循环就是一种遍历,至于什么是树形结构,emmmm…不是我们在这里讨论的重点。

上述的四个词可能看起来有点高深莫测,其实我们在前面已经讲过关于循环的内容,你要是在网上搜过的话,你会发现网上充斥着大量的讲关于迭代,循环和递归区别的文章,这里我们暂时先不比较,我们在本篇文章中先搞明白 Python 中的迭代。

逐个访问

在 Python 中,如果你想要访问对象中的每个元素,可以像下面这样做,我在这以列表举例:

>>> my_list = ['r','o','c','k','y']
>>> for i in my_list:
...     print(i,end=' ')
... 
r o c k y >>>

除了上述方法以外,还可以像下面这样:

>>> my_iter = iter(my_list)
>>> my_iter.__next__()
'r'
>>> my_iter.__next__()
'o'
>>> my_iter.__next__()
'c'
>>> my_iter.__next__()
'k'
>>> my_iter.__next__()
'y'
>>> my_iter.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

上面的 iter() 是一个内建函数,返回的就是一个迭代器对象,我在后面会专门再讲迭代器。

在 Python3 中,所有的迭代器对象都有 __next()__ 方法,迭代器,当然是可迭代的,在上面的例子中,__next()__ 就是要获得下一个对象,但是作为一个 “懒惰” 的程序员来说,上面的那种方法一个个的敲太麻烦了,所以就有了下面的方法:

>>> while True:
...     print(my_iter.__next__())
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
StopIteration

上面出现了错误,我们先不管,再来它一次:

>>> my_iter = iter(my_list)
>>> while True:
...     print(my_iter.__next__())
... 
r
o
c
k
y
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
StopIteration

看了上面演示的例子可以发现,如果我们用 for 循环来写的话,当到了末尾的时候就自动结束了,但是用了 __next__() 的话,当完成最后一个的时候它不会自动结束,还会向下继续,但是后面已经没有元素了,所以就发出了一个 StopIteration 的信息,即停止迭代。

在这我们还要再关注一下迭代器对象的另一个特点,看上上个的那个例子就可以知道,对象 my_iter 被迭代结束后,即每个元素都读取了一遍之后,指针就移到了最后一个元素后面,如果想要再访问的话,指针并没有自动移动到初始位置,所以会报 StopIteration,如果想要重新开始的话,就需要重新载入迭代对象。

到现在,对迭代器暂且有上述的了解,迭代器其实还要更深层次的使用,但是有一个典型的例子 -- 文件,这就是为什么我先把文件放在之前两天的文章来讲。

文件迭代器

现在有一个 “test.txt” 的文件,文件内容是:

My name is Rocky
I love Python
a,hhhhhhh

现在用迭代器来尝试操作这个文件,我们其实在之前两天讲述有关文件的知识的时候已经讲过了,就是用 readline() 一行一行的读,当然在实际操作中,我们是绝对不会这样做的,因为我们 “懒” 啊,一定要让它自动进行,比较常用的方法如下:

>>> f = open('test.txt')
>>> for line in f:
...     print(line,end=' ')
... 
My name is Rocky
 I love Python
 a,hhhhhhh >>>

上面的过程当然用 __next__() 也能够读取:

>>> f = open('test.txt')
>>> f.__next__()
'My name is Rocky\n'
>>> f.__next__()
'I love Python\n'
>>> f.__next__()
'a,hhhhhhh'
>>> f.__next__()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

如果用 __next__() 就可以直接读取每行的内容,这就说明文件是天生可迭代的对象,不需要用 iter() 转换。再者,我们用 for 来实现迭代,本质上就是自动调用 __next__() ,只不过这个工作被 for 偷偷的做了,所以 for 是活雷锋无疑了。

写在之后

初识迭代就到这结束了,其实迭代器远不止上述的那么简单,以后我们还会不断的遇到,我会在后续为大家带来深入理解迭代的文章。

最后感谢你能看到这里,希望我写的东西能够让你有到收获,但是我还是希望我在文章里插入的代码,你们能自己动手试一下,都很简单。原创不易,每一个字,每一个标点都是自己手敲的,所以希望大家能多给点支持,该关注关注,该点赞点赞,该转发转发,有什么问题欢迎在后台联系我,也可以在公众号找到我的微信加我。

本文分享自微信公众号 - Python空间(Devtogether)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-07-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏好好学java的技术栈

推荐几个IDEA插件,Java开发者撸码利器。

一款热部署插件,只要不是修改了项目的配置文件,用它都可以实现热部署。收费的,破解比较麻烦。不过功能确实很强大。算是开发必备神器了。热部署快捷键是control+...

9630
来自专栏10km的专栏

nanohttpd:实现跨域(CORS)请求

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

19420
来自专栏java 微风

JVM的新生代、老年代、MinorGC、MajorGC

原文链接:https://www.cnblogs.com/ygj0930/p/6522828.html

6520
来自专栏好好学java的技术栈

动画+原理+代码+优化,解读十大经典排序算法

排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。常见...

8150
来自专栏码客

Android Activity的启动模式

当通过这种模式来启动Activity时,Android总会为目标 Activity创建一个新的实例,并将该Activity添加到当前 Task栈中.注意,这种方...

7930
来自专栏实战docker

Java应用在docker环境配置容器健康检查

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

13320
来自专栏好好学java的技术栈

自己手撸一个 JSON 解析器

JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。采用...

9320
来自专栏码客

Mac OS 上设置 JAVA_HOME

由于需要,前几天在 OS X 上安装了 Oracle 的 Java 7。安装之后,发现由于我原来设置的 JAVA_HOME 为 /Library/Java/Ho...

8120
来自专栏码客

Mac上用MyEclipse创建Maven Web项目

右键 –> New –> Project –> 搜索Maven Project –> 设置存放位置 –> 选择项目类型为 maven-archetype-web...

6510
来自专栏码客

Android开发使用Lambda表达式

AndroidStudio从2.1开始官方通过Jack支持Java8,从而使用Lambda等特性。

12230

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励