#原创,转载请先联系

理论性的东西有点枯燥,耐心点看~

1.迭代是什么?

我们知道可以对list,tuple,dict,str等数据类型使用for...in的循环语法,从其中依次取出数据,这个过程叫做遍历,也叫迭代。迭代是访问集合元素的一种常用的方式。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2.可迭代对象是什么?

简单来说,可以用for...in循环语句,从其中依次取出数据的对象,就是可迭代对象。例如,列表、元组、字典、字符串都是可迭代对象。整数、浮点数、布尔值都是不可迭代的。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

3.迭代器是什么?

在可迭代对象进行迭代的时候,即用for...in...循环语法依次取出数据时,过程是怎样的呢?

我们发现,每迭代一次(即在for...in...中每循环一次)都会返回对象中的下一条数据,一直向后读取数据直到迭代了所有数据后结束。那么,在这个过程中就应该有一个“人”去记录每次访问到了第几条数据,以便每次迭代都可以返回下一条数据。我们把这个能帮助我们进行数据迭代的“人”称为迭代器(Iterator)。举个栗子,老师安排一个班的同学每节课上课前进行演讲,按学号顺序进行,A同学这节课演讲,老师就会记住这节课是A同学演讲,那么下节课就是B同学进行演讲...依次类推,在这个例子里,老师就是一个迭代器。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

4.怎样获取可迭代对象的迭代器?

我们可以通过iter()内置函数取得可迭代对象的迭代器。

list = [1,2,3,4,5]  # list是可迭代对象
lterator = iter(list) # 通过iter()方法取得list的迭代器
print(lterator) 输出:
<list_iterator object at 0x7f35e6537a20>

迭代器是获取到了,那么应该怎样用呢?

next()函数是通过迭代器获取下一个位置的值。

注意: 当我们已经迭代完最后一个数据之后,再次调用next()函数会抛出StopIteration的异常,来告诉我们所有数据都已迭代完成,不用再执行next()函数了。

list = [1,2,3,4,5]  # list是可迭代对象
lterator = iter(list) # 通过iter()方法取得list的迭代器
print(next(lterator)) #
print(next(lterator)) #
print(next(lterator)) #
print(next(lterator)) #
print(next(lterator)) #
print(next(lterator)) 输出:
1
2
3
4
5
Traceback (most recent call last):
File "/home/chichung/桌面/课堂练习/协程/iter方法取得可迭代对象的迭代器.py", line 8, in <module>
print(next(lterator))
StopIteration

看完觉得奇怪的同学,是不是觉得一个对象能拿出一个迭代器很amazing。好像编的一样,别急,继续看上去,下面有答案。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

5.判断一个对象是否可迭代

isinstance(object,classinfo)内置函数可以判断一个对象是否是一个已知的类型,类似 type()。

  • object -- 实例对象。
  • classinfo -- 可以是直接或间接类名、基本类型或者由它们组成的元组。

在这之前,还需要知道collections模块里的Iterable。通俗点讲,凡是可迭代对象都是这个类的实例对象。下面来验证一下:

import collections

print(isinstance([1, 2, 3], collections.Iterable))
print(isinstance((1,2,3), collections.Iterable))
print(isinstance({"name":"chichung","age":23}, collections.Iterable))
print(isinstance("sex", collections.Iterable))
print(isinstance(123,collections.Iterable))
print(isinstance(True,collections.Iterable))
print(isinstance(1.23,collections.Iterable)) 输出:
True
True
True
True
False
False
False

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

6.可迭代对象怎么可以获取迭代器呢?

看完第4点,有些人就感觉很奇怪,例如:[1,2,3]不就是一个列表,一个对象吗?怎么还能拿出一个迭代器来了?

首先,我们从第5点可以知道,可迭代对象其实都是collections模块里的Iterable类创建出来的实例的。你写一个列表,以为他不是任何类创建的,只是单纯一个列表?不是的,其实它就是Iterable类创建的实例对象。点进Iterable的类看一下,你会发现新大陆。

class Iterable(metaclass=ABCMeta):

    __slots__ = ()

    @abstractmethod
def __iter__(self): # 注意点
while False:
yield None

原来由Iterable创建的对象,是有一个魔方方法__iter__(self)的。这个方法就是返回一个迭代器的。所以,由Iterable类创建的实例对象,是可以拿出一个迭代器的。

接下来要说的有点绕......

之所以Iterable类创建的对象是可迭代对象,是因为Iterable类有这个方法!不信?我就来编写一个能创建可迭代对象的类。

import collections

class BecomeIterable:

    def __iter__(self):
"""返回一个空的迭代器"""
return None people = BecomeIterable()
print(isinstance(people, collections.Iterable)) 输出:
True

骚不骚?什么都没有,就一个魔法方法,创建的对象就是可迭代对象了。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

7.迭代器为什么能用next()函数进行迭代?

我们知道,可以用iter()函数,在可迭代对象中获取迭代器。例如:iterator = iter([1,2,3])

这样一看,迭代器也就是一个对象而已啊,为什么他可以用next()函数,一下子出来一个值,一下子又出来一个值。

其实是这样的,iter()函数能调用可迭代对象的魔方方法__iter__(),从而返回一个迭代器。怎么返回的呢?__iter__()方法是使用collections模块里的Iterator类来创建一个迭代器对象。

接下来看下Iterator的一部分源代码:

class Iterator(Iterable):

    __slots__ = ()

    @abstractmethod
def __next__(self):
'Return the next item from the iterator. When exhausted, raise StopIteration'
raise StopIteration def __iter__(self):
return self

是不是茅塞顿开了?和第6点的解释原理一样。这里就不详细解释了。稍微注意下魔方方法__next__()的最后一句,如果超出迭代方位就抛出StopIteration异常。

还有一点需要注意,迭代器的源代码也有__iter__()魔方方法,所以,Iterator也是一个可迭代对象呀!!!

所以,如果你喜欢在迭代器里面再取出迭代器也是可以的,但是好像有点无聊......目前还不知道有什么应用到......

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

8.创建一个迭代器类

理论讲完了额...不懂的还是要多看几遍。下面开始应用~

如果我们编写一段代码,想把结果一个一个迭代出来,这时候就需要编写迭代器类了。

class MyIterator():
def __init__(self):
self.list = []
self.position = 0 def add_name(self,name):
self.list.append(name) def __iter__(self):
return self # 返回一个迭代器 def __next__(self):
if self.position < len(self.list):
item = self.list[self.position]
self.position += 1
return item
else:
raise StopIteration people = MyIterator() # people对象既是一个迭代器,也是一个可迭代对象
people.add_name("张三")
people.add_name("李四")
people.add_name("王五") # 把people当做一个迭代器来看时
print(next(people))
print(next(people))
print(next(people)) # 把humen当做一个可迭代对象来看时
humen = MyIterator() # 因为迭代器只能用一次,再用会抛出错误,所以需要再创建
humen.add_name("张三")
humen.add_name("李四")
humen.add_name("王五")
iterator = iter(humen) # iter()方法获取可迭代对象的迭代器
print(next(iterator))
print(next(iterator))
print(next(iterator)) 输出:
张三
李四
王五
张三
李四
王五

注意看注释,如果原理都懂,这其实是一个很简单的例子。

python中的迭代器详解的更多相关文章

  1. python中threading模块详解(一)

    python中threading模块详解(一) 来源 http://blog.chinaunix.net/uid-27571599-id-3484048.html threading提供了一个比thr ...

  2. Python中time模块详解

    Python中time模块详解 在平常的代码中,我们常常需要与时间打交道.在Python中,与时间处理有关的模块就包括:time,datetime以及calendar.这篇文章,主要讲解time模块. ...

  3. 第7.19节 Python中的抽象类详解:abstractmethod、abc与真实子类

    第7.19节 Python中的抽象类详解:abstractmethod.abc与真实子类 一.    引言 前面相关的章节已经介绍过,Python中定义某种类型是以实现了该类型对应的协议为标准的,而不 ...

  4. python中常用模块详解二

    log模块的讲解 Python 使用logging模块记录日志涉及四个主要类,使用官方文档中的概括最为合适: logger提供了应用程序可以直接使用的接口API: handler将(logger创建的 ...

  5. 76.Python中F表达式详解

    F表达式是用来优化ORM操作数据库的. 举个例子:我们做口罩的公司要将所有员工的薪水增加2000元,如果按照正常的流程,应该是先从数据库中提取所有的员工的工资到Python内存中,然后使用Python ...

  6. python 中的unicode详解

    通过例子来看问题是比较容易懂的. 首先来看,下面这个是我新建的一个txt文件,名字叫做ivan_utf8.txt,然后里面随便编辑了一些东西. 然后来用控制台打开这个文件,同样也是截图: 这里就是简单 ...

  7. python 中model.py详解

    model详解 Django中遵循 Code Frist 的原则,即:根据代码中定义的类来自动生成数据库表. 创建表 基本结构 from django.db import models # Creat ...

  8. python 中的map 详解

    python中的map函数应用于每一个可迭代的项,返回的是一个结果list.如果有其他的可迭代参数传进来,map函数则会把每一个参数都以相应的处理函数进行迭代处理.map()函数接收两个参数,一个是函 ...

  9. Python 中的设计模式详解之:策略模式

    虽然设计模式与语言无关,但这并不意味着每一个模式都能在每一门语言中使用.<设计模式:可复用面向对象软件的基础>一书中有 23 个模式,其中有 16 个在动态语言中“不见了,或者简化了”. ...

随机推荐

  1. django视图之分页

    在网站开发时,肯定会遇到分页的事情需要处理,在django中也是如此,在Django中处理分页一般会使用到两个类django.core.paginator.Paginator和django.core. ...

  2. 另外一种C#多选下拉框

    链接: https://pan.baidu.com/s/1tnLgC9P_V8y9qHTYSg8xGA 密码: cwxj

  3. 判断python字典中key是否存在的两种方法

    今天来说一下如何判断字典中是否存在某个key,一般有两种通用做法,下面为大家来分别讲解一下: 第一种方法:使用自带函数实现. 在python的字典的属性方法里面有一个has_key()方法,这个方法使 ...

  4. 【Linux】——搭建redis

    1.准备安装文件 redis-3.0.5.tar.gz redis-desktop-manager(可视化管理工具) 2.解压.编译 软件存放目录:/usr/local/software 解压存放路径 ...

  5. 【工作感悟】——揭开“PM”的面纱

    [前言] 上次跟大家分享了面试的故事,小编觉得效果还不错,因此小编决定把工作感悟系列写下去,不过时间就不好说了.希望小伙伴们在评论列表中发表自己的看法和观点,积极参与啦~~ [背景] 初来Y公司,作为 ...

  6. DataBase -- Operator

    TOP子句用于规定要返回的记录的数目. SELECT TOP number | percent column_name FROM table_name LIKE操作符用于在WHERE子句中搜索列的指定 ...

  7. 2017 Multi-University Training Contest - Team 2 TrickGCD(组合数学)

    题目大意: 给你一个序列An,然后求有多少个序列Bn 满足Bi<=Ai,且这个序列的gcd不为1 题解: 考虑这样做 枚举一个因子k,然后求出有多少个序列的gcd包含这个因子k 然后把结果容斥一 ...

  8. Problem Collection I 位运算

    XOR ARC 092B CF 959E xor-MST CF 959F

  9. [洛谷P3153] [CQOI2009]跳舞

    题目大意:有n个女生,n个男生,每次一男一女跳舞.同一队只会跳一次.每个男孩最多只愿意和k个不喜欢的女孩跳舞,女孩同理.问舞会最多能有几首舞曲? 题解:二分跳了多少次舞,每次重建图,建超级原点和汇点, ...

  10. 洛谷 P2414 [NOI2011]阿狸的打字机 解题报告

    P2414 [NOI2011]阿狸的打字机 题目背景 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机. 题目描述 打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P'两个字母 ...