本节内容
1、简书
2、可迭代对象
3、迭代器
4、rang方法
5、总结
一、简述
我们经常使用for循环去遍历一些序列数据,但是我们有的时间发现for循环的效率很低,而且很占用了大量的硬件资源,但是有的for循环遍历效率很高,而且很节省硬件资源,这是为什么呢?有人说是生成器的原因。
二、可迭代对象
1、for循环数据类型
- 集合数据类型,如:list、tuple、dict、set、str、bytes(字节)等。
- 生成器(generator),包括生成器和带yield的生成器函数。
2、定义
可迭代对象(Iterable
):直接用于for循环遍历数据的对象
3、用isinstance()方法判断一个对象是否是Iterable
对象
Iterable
对象
1
2
3
4
5
6
7
8
9
10
11
|
>>>
from
collections
import
Iterable
>>>
isinstance
([],Iterable)
#列表
True
>>>
isinstance
((),Iterable)
#元组
True
>>>
isinstance
({},Iterable)
#字典
True
>>>
isinstance
(
'abc'
,Iterable)
#字符串
True
>>>
isinstance
(
100
,Iterable)
#整型
False
|
注:生成器不但可以作用于for循环,还可以被__next__()函数不断调用,并且返回下一个值,直到最后抛出StopIteration
错误表示无法继续返回下一个值而抛出的异常。
三、迭代器
1、定义
迭代器(Iterator
):可以用__next__()函数调用并不断的返回下一个值的对象称为迭代器。
2、用isinstance()方法判断一个对象是否是Iterator
对象
Iterator
对象
1
2
3
4
5
6
7
8
9
|
>>>
from
collections
import
Iterator
>>>
isinstance
((i
*
2
for
i
in
range
(
5
)),Iterator)
#生成器
True
>>>
isinstance
([],Iterator)
#列表
False
>>>
isinstance
({},Iterator)
#字典
False
>>>
isinstance
(
'abc'
,Iterator)
#字符串
False
|
通过上面的例子可以看出,生成器都是Iterator
对象,但是list、dict、str虽然是Iterable
对象,却不是Iterator
对象。
3、iter()函数
功能:把list、dict、str等Iterable
对象变成Iterator
对象。
1
2
3
4
5
|
>>>
from
collections
import
Iterator
>>>
isinstance
(
iter
([]),Iterator)
True
>>>
isinstance
(
iter
({}),Iterator)
True
|
4、为什么list、dict、str等数据类型不是Iterator
?
这是因为python的Iterator
对象表示的是一个数据流,Iterator对象可以被__next__()函数调用并不断返回下一个数据,直到没有数据时抛出StopIteration
错误。可以把这个数据流看做是一个有序序列,但我们却不能提前知道序列的长度,只能不断通过__next__()函数实现按需计算下一个数据,所以Iterator
的计算是惰性的,只有在需要返回下一个数据时才会计算。
注:Iterator
甚至可以表示一个无限大的数据流,例如:全体自然数。而使用list是永远不可能存储全体自然数的。
四、rang()方法
在python2.7和python3的range()方法实现的原理是不一样的,下面我们就来用代码看看,代码如下:
1
2
3
4
5
6
|
>>>
range
(
5
)
#python2.7
[
0
,
1
,
2
,
3
,
4
]
>>>
xrange
(
5
)
#python2.7
xrange
(
5
)
>>>
range
(
5
)
#python3.5
range
(
0
,
5
)
|
从上面的代码可以看出,在python2.7中rang()只是一个list,在python3中是一个迭代器,python2.7中xrange()跟python3中的range()功能是一样的。
python3中的range()方法实现的原理如下:
1
2
|
for
x
in
range
(
5
):
pass
|
实际相当于:
1
2
3
4
5
6
7
8
9
10
|
# 首先获得Iterator对象:
it
=
iter
([
1
,
2
,
3
,
4
,
5
])
# 循环:
while
True
:
try
:
# 获得下一个值:
x
=
next
(it)
except
StopIteration:
# 遇到StopIteration就退出循环
break
|
五、总结
- 凡是可以作用于for循环的对象都是
Iterable
类型。 - 凡是作用于__next__()函数的对象都是
Iterator
类型,它们表示一个惰性计算的序列。 - 集合数据类型,例如:list、dict、str等,是
Iterable
但是不是Iterator
- 集合数据类型可以通过
iter
()函数获得一个Iterator
对象。