为了更深入一点理解可迭代对象和迭代器,读了几篇不错的文章:
Python实践18-可迭代对象和迭代器 - 曾月天的文章 - 知乎
https://zhuanlan.zhihu.com/p/33113366
给妹子讲python--14可迭代对象和迭代器 - 酱油哥的文章 - 知乎
https://zhuanlan.zhihu.com/p/32508947
完全理解 Python 迭代对象、迭代器、生成器
http://python.jobbole.com/87805/
基础概念的理解
relationships.png可迭代对象:
- 可以用for循环遍历的对象统称为可迭代对象(Iterable Object)
- 可迭代对象必须内部实现
__iter__()
函数,返回一个迭代器。
迭代器:
- 可以被
next()
函数调用,不断返回下一个值的对象被成为迭代器(Iterator) - 迭代器内部实现
__iter__()
函数,返回迭代器对象本身 - 迭代器内部实现next()函数(Python3是
__next__()
函数),返回下一个元素,遍历完成时需要抛出StopIteration异常。
可迭代对象和迭代器的关系:
- 可迭代对象的for循环的实际是靠不断将可迭代对象的迭代器传给next()调用实现的。
- 在可迭代对象上调用iter(),就会生成一个迭代器。即
迭代器 = iter(可迭代对象)
生成器:一种特殊的迭代器,以一种懒加载的模式生成值
代码示例:
In [1]: L = [1, 2, 3]
In [2]: I = iter(L) # 将可迭代对象转换成迭代器
In [3]: print(L)
[1, 2, 3]
In [4]: print(I)
<list_iterator object at 0x10b89fb70>
In [5]: # 可迭代对象可以通过for语句循环迭代,但是不能使用next()函数
In [6]: for x in L: print(x)
1
2
3
In [7]: print(next(L))
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-318320db5765> in <module>()
----> 1 print(next(L))
TypeError: 'list' object is not an iterator
In [8]: # 迭代器可以使用next函数调用
In [9]: print(next(I))
1
In [10]: print(next(I))
2
In [11]: print(next(I))
3
In [12]: print(next(I)) # 迭代最后超出总长度之后报StopIteration异常
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-12-9e98ab551472> in <module>()
----> 1 print(next(I)) # 迭代最后超出总长度之后报StopIteration异常
StopIteration:
动手写一个:求斐波那契
# 创建可迭代对象
class FibonacciIterable(object):
def __init__(self, max):
self.max = max
# 重写__iter__函数,调用迭代器
def __iter__(self):
return FibonacciIterator(self.max)
# 创建迭代器
class FibonacciIterator:
# 初始化迭代器
def __init__(self, max):
self.max = max
self.prev = 0
self.curr = 1
# 迭代器中重写__iter__函数,返还自身
def __iter__(self):
return self
# 重写__next__函数,编写每次调用时的逻辑
def __next__(self):
if self.curr <= self.max:
value = self.curr
self.curr += self.prev
self.prev = value
return value
else: # 超出迭代范围时,返还StopIteration异常
raise StopIteration
max = 10
print('-' * 30)
# 可迭代对象
f_iterable = FibonacciIterable(max)
print(list(f_iterable))
for x in f_iterable:
print(x)
print('-' * 30)
# 迭代器
f_iterator = FibonacciIterator(max)
print(next(f_iterator))
print(next(f_iterator))
print(next(f_iterator))
print(next(f_iterator))
print(next(f_iterator))
print(next(f_iterator))
print(next(f_iterator))
执行结果:
------------------------------
[1, 1, 2, 3, 5, 8]
1
1
2
3
5
8
------------------------------
1
1
2
3
5
8
Traceback (most recent call last): File "/Users/liuchen/MyDev/Fibonacci.py", line 100, in <module>
print(next(f_iterator))
File "/Users/liuchen/MyDev/Fibonacci.py", line 79, in __next__
raise StopIteration
StopIteration
网友评论