可迭代对象(iterable)[可迭代对象的内部实现了__iter__方法,该方法返回一个迭代器对象]
1
2
3
4
5
6
7
8
9
10
11
12
13
|
>>> x
=
[
1
,
2
,
3
]
>>> y
=
iter
(x)
>>> z
=
iter
(x)
>>>
next
(y)
1
>>>
next
(y)
2
>>>
next
(z)
1
>>>
type
(x)
<
class
'list'
>
>>>
type
(y)
<
class
'list_iterator'
>
|
迭代器是具有迭代类型,比如list_iterator
,set_iterator
举例说明:
1
2
3
|
x
=
[
1
,
2
,
3
]
for
elem
in
x:
...
|
真实的情况是:
反编译该段代码,你可以看到解释器显示地调用GET_ITER
指令,相当于调用iter(x)
,FOR_ITER
指令就是调用next()
方法,不断地获取迭代器中的下一个元素,但是你没法直接从指令中看出来,因为他被解释器优化过了。
迭代器(itertor)
迭代器是一个带状态的对象,任何实现了__iter__ 和 __next__(python2中实现了next())方法的对象都是迭代器。__iter__返回迭代器自身,__next__返回容器中的下一个值,如果容器中没有更多的元素,则抛出异常。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
class
Fib:
def
__init__(
self
):
self
.prev
=
0
self
.curr
=
1
def
__iter__(
self
):
return
self
def
__next__(
self
):
value
=
self
.curr
self
.curr
+
=
self
.prev
self
.prev
=
value
return
value
>>> f
=
Fib()
>>>
list
(islice(f,
0
,
10
))
[
1
,
1
,
2
,
3
,
5
,
8
,
13
,
21
,
34
,
55
]
|
Fib既是一个可迭代对象(实现了__iter__方法),又是一个迭代器实现了(__next__方法),实例变量prev和curr用户维护迭代器内部的状态,每一次调用next()方法的时候做两件事:
1、为下一次调用next()方法修改状态
2、为当前这次调用生成返回结果
我的终极实例,助你理解迭代器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
class
MyIter:
def
__init__(
self
, start
=
0
, end
=
0
):
print
(
'程序的init'
)
self
.start
=
start
self
.end
=
end
def
__iter__(
self
):
print
(
'我在这里制造了一个迭代器'
)
return
self
# 这个地方如果不return self 那么c 就不具备可迭代的能力
def
__next__(
self
):
print
(
'这里调用 __next__方法'
,
self
.start)
if
self
.start <
self
.end:
i
=
self
.start
self
.start
+
=
1
return
i
else
:
raise
StopIteration()
c
=
MyIter(
0
,
5
)
# 代码到这里只是创造了一个迭代器
for
i
in
c:
# 代码到这里 会调用__iter__和__next__ 具有迭代的能力
print
(i)
>>>>>>>>>程序的init
我在这里制造了一个迭代器
这里调用 __next__方法
0
0
这里调用 __next__方法
1
1
这里调用 __next__方法
2
2
这里调用 __next__方法
3
3
这里调用 __next__方法
4
4
这里调用 __next__方法
5
|
生成器(generator)
生成器是一种特殊的迭代器,不过这种迭代器显得更加优雅,生成器不需要写__iter__和__next__方法,只需要一个yield关键字。
生成器一定是迭代器(反之不成立)
生成器表达式(generator expression)
生成器表达式是列表推导式的生成器版本
1
2
3
4
5
|
>>> a
=
(x
*
x
for
x
in
range
(
10
))
>>> a
<generator
object
<genexpr> at
0x401f08
>
>>>
sum
(a)
285
|
总结:
* 容器是一系列元素的集合,str、list、set、dict、file、sockets都可以看作是容器
容器都是可以被迭代的
* 可迭代对象实现了__iter__ 方法,该方法返回一个迭代器对象
* 迭代器持有一个内部状态字段用户记录下次迭代返回值它实现了 __iter__ 和 __next__方法,迭代器不会一次性把所有的元素加载到内存,而是需要的时候才返回结果
* 生成器是一种特殊的迭代器,返回值是通过yeild
本文转自http://www.cnblogs.com/mosson/p/8398187.html#_label0