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

可迭代对象(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()

运行结果为:

最新文章

  1. [连载]《C#通讯(串口和网络)框架的设计与实现》- 7.外部接口的设计
  2. iPhone开发常问的十个问题
  3. mongodb csv 文件导入数据库,删除特定字段
  4. HDU 4771 Stealing Harry Potter's Precious
  5. dojo.hitch 原理
  6. C# 让textbox 只能输入数字的方法
  7. oj 小黑华丽的逆袭机会
  8. (摘录)MSMQ的简单介绍
  9. jquery mobile Checkbox动态添加刷新及事件绑定
  10. 一.windows环境下rabbitMQ的的安装和配置
  11. idea将maven项目打包成war包的方式,以及使用war包
  12. Python进阶1---高阶函数、柯里化
  13. 记录一次spark连接mysql遇到的问题
  14. P1880 [NOI1995]石子合并(区间DP)
  15. Xamarin Mono Android实现“再按一次退出程序”
  16. swift MD5 加密方法
  17. windows安装 Microsoft Visual c++
  18. 【Alpha】阶段第六次Scrum Meeting
  19. HahMap
  20. 按Right-BICEP要求的测试用例

热门文章

  1. JavaWeb网上图书商城完整项目--day03-1.图书模块功能介绍及相关类创建
  2. drf-Authentication认证
  3. webstom 汉化,激活
  4. 栈的顺序存储和链式存储c语言实现
  5. (八十九)c#Winform自定义控件-自定义滚动条(treeview、panel、datagridview、listbox、listview、textbox)
  6. 廖雪峰Python教学课后作业---datetime
  7. 关于延迟段创建-P1
  8. Demo_2:Qt实现猜字小游戏
  9. 深入了解JVM-方法区
  10. JS断点调试,必备的javaScript的debug调试技巧