迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

可迭代对象(Iterable)

能够被循环遍历(迭代)的对象称为可迭代对象,如list、tuple、dict、set、str等。使用以下语句判断是否是可迭代对象

>>> from collections.abc import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False

从代码层面上来说,当class中实现了__iter__方法,则该类创建的对象即为可迭代对象

>>> class MyList(object):
... def __init__(self):
... self.container = []
... def add(self, item):
... self.container.append(item)
... def __iter__(self):
... """返回一个迭代器"""
... # 我们暂时忽略如何构造一个迭代器对象
... pass
...
>>> mylist = MyList()
>>> from collections import Iterable
>>> isinstance(mylist, Iterable)
True
>>>
# 这回测试发现添加了__iter__方法的mylist对象已经是一个可迭代对象了

可迭代对象的本质

可迭代对象的本质就是可以提供一个迭代器,该迭代器能记录每次访问到了第几条数据,以便每次迭代都可以返回下一条数据。

迭代器(Iterator)

要使得可迭代对象能够正常的循环迭代,必须实现__iter__方法返回一个迭代器。我们在迭代一个可迭代对象的时候,实际上就是先获取该对象提供的一个迭代器,然后通过这个迭代器来依次获取对象中的每一个数据。

要自定义一个迭代器,必须实现__iter__方法和__next__方法。例:

from collections.abc import Iterable
import time class MyList(object):
"""自定义一个可迭代对象""" def __init__(self):
self.content = list() def add(self, item):
self.content.append(item) def __iter__(self):
# 1.要使一个对象是可迭代对象,必须实现__iter__方法
# 2.要使一个对象迭代时能每次都返回一个值,必须让__iter__返回一个迭代器对象
# 创建迭代器对象
myiterator = MyIterator(self)
return myiterator class MyIterator(object):
"""自定义一个迭代器,必须实现__iter__方法和__next__方法""" def __init__(self, mylist_obj):
self.mylist = mylist_obj
self.current = 0 def __iter__(self):
pass def __next__(self):
"""每次迭代时返回的值实际是通过__next__方法返回的"""
# 1.定义一个下标current,每次调用时+1,用来实现每次调用__next__时,返回下一个值
# 2.注意判断下标current自增时是否会越界,若越界则手动抛出StopIteration异常
# 外层for循环迭代时,若遇到StopIteration异常,则会停止迭代
if self.current == len(self.mylist.content):
raise StopIteration
value = self.mylist.content[self.current]
self.current += 1
return value def main():
my_list = MyList()
my_list.add(11)
my_list.add(22)
my_list.add(33)
print('my_list是不是可迭代对象:', isinstance(my_list, Iterable))
my_list_iterator = iter(my_list)
print('my_list返回的迭代器为:', my_list_iterator)
print('my_list的下一个值为:', next(my_list_iterator))
for i in my_list:
print(i)
time.sleep(1) if __name__ == '__main__':
main()

运行结果为:

上述代码定义了两个类,共同实现一个可迭代对象,我们可以将第二个迭代器类中使用到的方法放到第一个可迭代对象中,这样第一个可迭代对象同时也是一个迭代器。__iter__方法返回的就是自己self,如:

import time

class MyList(object):
"""自定义迭代器""" def __init__(self):
self.content = list()
self.current = 0 def add(self, value):
self.content.append(value) def __iter__(self):
return self def __next__(self):
# 若越界则抛出StopIteration异常
if self.current == len(self.content):
raise StopIteration
# 不越界则返回当前迭代的值,并自增下标current
value = self.content[self.current]
self.current += 1
return value def main():
# 创建迭代器对象
my_list = MyList()
  print('my_list是不是一个可迭代对象', isinstance(my_list, Iterable))
  print('my_list是不是一个迭代器', isinstance(my_list, Iterator))
# 添加值
my_list.add('小明')
my_list.add('小红')
my_list.add('小花')
# 遍历my_list
for value in my_list:
print(value)
time.sleep(0.5) if __name__ == '__main__':
main()

运行结果为:

迭代器实现斐波那契数列

import time

class Fibonacci(object):
def __init__(self, num):
self.a = 0
self.b = 1
self.num = num
self.current = 0 def __iter__(self):
return self def __next__(self):
if self.current == self.num:
raise StopIteration
temp = self.a
self.a, self.b = self.b, self.a + self.b
self.current += 1
return temp def main():
fibonacci_1 = Fibonacci(10)
fibonacci_2 = Fibonacci(5)
fibonacci_3 = Fibonacci(8)
# for循环接收可迭代对象
for i in fibonacci_1:
print(i)
time.sleep(0.2)
# list接收可迭代对象
lst = list(fibonacci_2)
print(lst)
# tuple接收可迭代对象
tpl = tuple(fibonacci_3)
print(tpl) if __name__ == '__main__':
main()

运行结果为:

python-多任务编程03-迭代器(iterator)的更多相关文章

  1. Python并发编程03 /僵孤进程,孤儿进程、进程互斥锁,进程队列、进程之间的通信

    Python并发编程03 /僵孤进程,孤儿进程.进程互斥锁,进程队列.进程之间的通信 目录 Python并发编程03 /僵孤进程,孤儿进程.进程互斥锁,进程队列.进程之间的通信 1. 僵尸进程/孤儿进 ...

  2. Python网络编程03 /缓存区、基于TCP的socket循环通信、执行远程命令、socketserver通信

    Python网络编程03 /缓存区.基于TCP的socket循环通信.执行远程命令.socketserver通信 目录 Python网络编程03 /缓存区.基于TCP的socket循环通信.执行远程命 ...

  3. python函数式编程之迭代器

    什么是迭代器 顾名思义,就是更新换代的意思 python中的迭代器就是根据上一个结果生成下一个结果,一直循环往复不断重复的过程 迭代器有两个特点: 1.不断重复同一个过程 2.根据上一个结果生成下一个 ...

  4. python生成器(generator)、迭代器(iterator)、可迭代对象(iterable)区别

    三者联系 迭代器(iterator)是一个更抽象的概念,任何对象,如果它的类有next方法(next python3)和__iter__方法返回自己本身,即为迭代器 通常生成器是通过调用一个或多个yi ...

  5. Python学习笔记014——迭代器 Iterator

    1 迭代器的定义 凡是能被next()函数调用并不断返回一个值的对象均称之为迭代器(Iterator) 2 迭代器的说明 Python中的Iterator对象表示的是一个数据流,被函数next()函数 ...

  6. Python 生成器 Generator 和迭代器 Iterator

    #最近一周刚开始接触python,基本的语法,和使用特性和Java差别还是蛮大的. 今天接触到Python的迭代器和生成器有点不是很明白,所以搜索了先关资料整理了一些自己的理解和心得 简述(Profi ...

  7. Python进阶内容(四)--- 迭代器(Iterator)与生成器(Generator)

    迭代器 我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是generator,包括生成器和带yield的ge ...

  8. Python核心编程的四大神兽:迭代器、生成器、闭包以及装饰器

      生成器 生成器是生成一个值的特殊函数,它具有这样的特点:第一次执行该函数时,先从头按顺序执行,在碰到yield关键字时该函数会暂停执行该函数后续的代码,并且返回一个值:在下一次调用该函数执行时,程 ...

  9. python基础编程:生成器、迭代器、time模块、序列化模块、反序列化模块、日志模块

    目录: 生成器 迭代器 模块 time 序列化 反序列化 日志 一.生成器 列表生成式: a = [1,2,3,3,4,5,6,7,8,9,10] a = [i+1 for i in a ] prin ...

  10. Python的迭代器(iterator)和生成器(constructor)

    一.迭代器(iterator) 1.迭代器的概述 在Python中,for循环可以用于Python中的任何类型,包括列表.元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器 迭代器 ...

随机推荐

  1. 使用json-server与Mockjs搭建模拟服务

    为什么使用 在项目开发中,常常需要边写前端页面边写后端接口,但是后端接口服务往往是滞后于前端开发的,或者是不能及时提供的.出于前端开发的迅速和便捷去考虑,我们可以根据后端接口数据结构去模拟(mock) ...

  2. 多线程高并发编程(12) -- 阻塞算法实现ArrayBlockingQueue源码分析(1)

    一.前言 前文探究了非阻塞算法的实现ConcurrentLinkedQueue安全队列,也说明了阻塞算法实现的两种方式,使用一把锁(出队和入队同一把锁ArrayBlockingQueue)和两把锁(出 ...

  3. js 字符串排序

    this.regionsList = result.sort((a, b) => a.warehouseAreaCode.localeCompare(b.warehouseAreaCode)); ...

  4. python基础知识练习1

    1.要求:输入A.B.C获得方程的解. 分析:通过input函数接收A,B,C的值.通过公式计算出detal的值,再根据条件进行判断,输出所需要的值: def args_input(): try: A ...

  5. 奇妙的 CSS MASK

    本文将介绍 CSS 中一个非常有意思的属性 mask . 顾名思义,mask 译为遮罩.在 CSS 中,mask 属性允许使用者通过遮罩或者裁切特定区域的图片的方式来隐藏一个元素的部分或者全部可见区域 ...

  6. Web移动端 自适应缩放界面

    在开发App端的网页时,要适配iphone.ipad.ipod.安卓等各种机型,一般是直接使用em.px转em.界面缩放. 本章是通过将界面缩放,等比例显示在各机型上.过程中遇到了些问题和大坑~ 然后 ...

  7. day48 navicat使用及pymysql的使用

    目录 一.navicat介绍 1 基本使用 2 练习题 2.1 查询所有的课程的名称以及对应的任课老师姓名 2.2 查询平均成绩大于八十分的同学的姓名和平均成绩 2.3 查询没有报李平老师课的学生姓名 ...

  8. CTFHub_技能树_远程代码执行

    RCE远程代码执行 命令分割符: linux: %0a .%0d .; .& .| .&&.|| 分隔符 描述 ; 如果每个命令都被一个分号(:)所分隔,那么命令会连续地执行下 ...

  9. SQLAlchemy04 /SQLAlchemy查询高级

    SQLAlchemy04 /SQLAlchemy查询高级 目录 SQLAlchemy04 /SQLAlchemy查询高级 1.排序 2.limit.offset和切片操作 3.懒加载 4.group_ ...

  10. 数据可视化之DAX篇(十)在PowerBI中累计求和的两种方式

    https://zhuanlan.zhihu.com/p/64418286 假设有一组数据, 已知每一个产品贡献的利润,如果要计算前几名产品的贡献利润总和,或者每一个产品和利润更高产品的累计贡献占总体 ...