for 循环 是咱们在 Python 里很是经常使用的一个语法,但你有没有思考过 for 循环是怎样实现的?编程
若是你之前接触过 C++,应该会知道相似 for (int i = 0; i < 100; i++)
这样的写法,它定义了 循环的执行条件 i < 100
以及 每次循环结束后执行的语句 i++
,而 for
自己只起到让代码重复执行的做用,并无什么额外的功能。这在 Python 中其实更像是 while 循环:函数
i = 0 while i < 100: # 执行循环代码 i += 1
但 Python 里的 for 循环却不同。使用 for
时,咱们没有额外指定结束条件,也不须要一个用来计数的数值,甚至能够经过一个字符串进行循环。之因此能够这样,是由于 Python 中的 迭代器(Iterator) 以及 可迭代对象(Iterable) 。人工智能
若是一个对象定义了 __iter__
和 __next__
两个方法, 它就是一个迭代器 。对于迭代器来讲,__iter__
返回的是它自身 self ,__next__
则是 返回迭代器中的下一个值 ,若是没有值了则抛出一个 StopIteration
的异常。关于这点,你能够想象成一个只进不退的标记位,每次调用 __next__
,就会将标记日后移一个元素并返回,直到结束。spa
有了迭代器的概念以后,若是一个对象定义了 __iter__
和方法,返回一个迭代器对象,那么 它就是一个可迭代的对象 。code
从表现上来讲,一个对象 可迭代 ,那么它就能够被 for 循环使用。好比咱们常常用到的 list、dict、str 等类型,都是可迭代的,因此也就能够经过 for 循环进行遍历,或者更准确的说:被迭代。对象
有一点绕,咱们再来理一理迭代器(Iterator)和可迭代(Iterable)这两个的差异:继承
__iter__
方法。反过来则不成立。(事实上,Iterator 就是 Iterable 的子类)__iter__
方法 返回的是自身,并不产生新实例 。而可迭代对象的 __iter__
方法一般会生成一个新的迭代器对象。__iter__
、__next__
分别对应于 Python 的内置函数 iter()
和 next()
:好比 iter(aList)
就至关于 aList.__iter__()
。递归
因此关于上述两点,咱们能够有如下的例子来验证:ci
迭代器和可迭代之间的继承关系。rem
__iter__
方法返回值的区别。id 相同表明是同一个实例。
明白了上述的概念以后,for 循环的实现就好理解了:
__iter__
方法,获取相应的迭代器__next__
方法的返回值赋值给循环变量StopIteration
异常,循环结束再来看个例子:
思考题: 想想为何迭代器 aListIter 被 for 循环迭代第二次的时候就没有输出了?
既然 __next__
方法能够本身定义,咱们也能够本身实现一个迭代器。好比要 输出一个斐波那契数列 (每一位数值都是前两位数值之和,原题回复关键字 906 ),一般的作法是循环,“高级”一点的作法是递归。但咱们也能够直接写一个斐波那契迭代器:
# 定义迭代器 class Fibonacci(): def __init__(self): self.a = 0 self.b = 1 def __iter__(self): return self def __next__(self): # 结束条件 if self.b > 100: raise StopIteration # 更新一次数值 self.a, self.b = self.b, self.a + self.b return self.a # 建立迭代器 fib = Fibonacci() # 进行迭代 for f in fib: print(f, end=' ')
输出:
1 1 2 3 5 8 13 21 34 55 89
这个例子中,咱们并无保存一个序列,只是定义了一种规则,就也能够被迭代。
使用迭代器的好处在于:它是一种 延迟操做 ,即当须要用到的时候才去产生结果。好比对于一个序列来讲,若是咱们要遍历它,并不须要再一开始就把全部元素都生成好,而是只须要知道每一个元素的下一个元素是什么就能够了。这样能够节省不少空间,尤为对于数量很大的集合来讲。
若是你不懂迭代器的概念,并不影响在代码中使用 for 循环。但了解以后,你会对代码理解得更透彻,同时这也是为咱们后面要讲到的 生成器 作铺垫。
════
其余文章及回答:
如何自学Python | 新手引导 | 精选Python问答 | Python单词表 | 人工智能 | 爬虫 | 我用Python | requests | 计算机视觉 | 字符播放器 | 一图学Python
欢迎搜索及关注公众号: Crossin的编程教室