Python迭代器总结

首先要说明的几个概念

1 什么是可迭代对象(Iterable)

>>> s = 'hello'
>>> for i in s:
	print(i)
	
h
e
l
l
o
>>> from collections.abc import Iterable,Iterator
>>> print(isinstance(s,Iterable))
True

总结:凡是可作用于for循环的对象都是可迭代对象,它们都是Iterable类型的对象,例如string,list,tuple,dict等类型

2 什么是迭代器(Iterator)

可迭代对象就是迭代器吗?

>>> s = 'hello'
>>> print(isinstance(s,Iterator))
False
>>> 

 显然不一定,例如string,list就不是,那什么是迭代器呢?

迭代器(Iterator)是指可以被next函数调用并不断返回下一个值的对象。

如何获取一个迭代器?

>>> s = 'hello'
>>> iter = iter(s)
>>> print(isinstance(iter,Iterator))
True
>>> for i in iter:
	print(i)

	
h
e
l
l
o
>>> 

通过将一个可迭代对象(Iterable)传入iter函数可返回一个迭代器(Iterator).

自定义迭代器

>>> class Av(object):
	def __init__(self,list):
		self.list = list
	def __next__(self):
		
		if len(self.list):
			return self.list.pop(0)
		else:
			raise StopIteration
	def __iter__(self):
		return self

	
>>> av = Av([1,2,3,4,5])
>>> print(isinstance(av,Iterable))
True
>>> print(isinstance(av,Iterator))
True
>>> for i in av:
	print(i)

	
1
2
3
4
5
>>> 

通过以上代码我们不难看出

 Iterator是Iterable的子类

 当类实现了__iter__函数则该类是Iterable(可迭代)类型

 当Iterable类实现了__next__函数则该类是Iterator(生成器)类型

3 生成器generator

生成器是一种特殊的迭代器,当在函数中添加yield语句后,调用该函数会返回一个generator对象

>>> def gen():
	for i in range(10):
		yield i**2

		
>>> print(type(gen))
<class 'function'>
>>> g = gen()
>>> print(type(g))
<class 'generator'>
>>> for i in g:
	print(i)

	
0
1
4
9
16
25
36
49
64
81
>>> g2 = gen()
>>> for i in g2:
	print(i)

	
0
1
4
9
16
25
36
49
64
81
>>> 

一个生成器对象遍历一次后会失效,原因是迭代器是不可逆的。

 当for循环作用于生成器对象时,会执行函数内部的代码直到遇到yield语句为止并返回yield后的值,然后将函数程序挂起保存执行现场等待下一次遍历直到遇到return语句或执行完函数的最后一句代码。

生成器对象还可以通过__next__函数来不断返回下一个值来进行遍历,直到抛出StopItIteration异常。

>>> g3 = gen()
>>> g3.__next__()
0
>>> g3.__next__()
1
>>> g3.__next__()
4
>>> g3.__next__()
9
>>> g3.__next__()
16
>>> g3.__next__()
25
>>> g3.__next__()
36
>>> g3.__next__()
49
>>> g3.__next__()
64
>>> g3.__next__()
81
>>> g3.__next__()
Traceback (most recent call last):
  File "<pyshell#64>", line 1, in <module>
    g3.__next__()
StopIteration
>>> 

这种方法太麻烦了,我们一般使用for循环。

补充:

Python的for循环本质上就是不断调用next函数实现的,next函数的参数类型必须是一个Iteraotr生成器(有__next__属性)类型 ps:next函数应该是通过调用生成器对象的__next__ 属性来完成遍历的,因为一个Iterator类型必须实现__next__函数。

>>> g4 = gen()
>>> while True:
	try:
		x = next(g4)
		print(x)
	except StopIteration:
		break

	
0
1
4
9
16
25
36
49
64
81
>>> 
>>> it = iter('hello')
>>> while True:
	try:
		x = next(it)
		print(x)
	except StopIteration:
		break

	
h
e
l
l
o
>>> 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值