参考:
http://c.biancheng.net/view/6593.html
https://www.geeksforgeeks.org/introduction-iterators-c/
https://www.runoob.com/python3/python3-iterator-generator.html
return比较简单,就是函数返回值
先来谈谈yield(生成器)的来源,在谈生成器之前再谈一下迭代器
很多语言都提供了迭代器,C++/Python都有
先看C++的
是一个指向容器的对象,C++ STL 六大组件之一,用来操纵容器。
在 C++ STL 中,对容器中数据的读和写,是通过迭代器完成的,扮演着容器和算法之间的胶合剂。
我自己用迭代器,一般就是begin(),end(),++。感觉就是个安全的指针
在Python中,迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
迭代器有两个基本的方法:iter() 和 next()。
字符串,列表或元组对象都可用于创建迭代器:
>>> list=[1,2,3,4]
>>> it = iter(list) # 创建迭代器对象
>>> print (next(it)) # 输出迭代器的下一个元素
1
>>> print (next(it))
2
>>>
iter()创建迭代对象,就好像把list变成一个容器了,接下来通过next(++)访问
#!/usr/bin/python3
list=[1,2,3,4]
it = iter(list) # 创建迭代器对象
for x in it:
print (x, end=" ")
类似于C++访问数组
#include <list>
#include <iostream>
#include <algorithm> //要使用操作迭代器的函数模板,需要包含此文件
using namespace std;
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
list <int> lst(a, a+5);
list <int>::iterator p = lst.begin();
advance(p, 2); //p向后移动两个元素,指向3
cout << "1)" << *p << endl; //输出 1)3
advance(p, -1); //p向前移动一个元素,指向2
cout << "2)" << *p << endl; //输出 2)2
list<int>::iterator q = lst.end();
q--; //q 指向 5
cout << "3)" << distance(p, q) << endl; //输出 3)3
iter_swap(p, q); //交换 2 和 5
cout << "4)";
for (p = lst.begin(); p != lst.end(); ++p)
cout << *p << " ";
return 0;
}
所以通过C++的迭代器理解Python的迭代器
接下来到了终点了,Python的生成器
在 Python 中,使用了 yield 的函数被称为生成器(generator)。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
生成器的在于可以像取list一样操作,但是又不要求数据立刻取到,比如通过list读取图片,每次返回一张图片,等到list访问完了,迭代结束
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
#!/usr/bin/python3
import sys
def fibonacci(n): # 生成器函数 - 斐波那契
a, b, counter = 0, 1, 0
while True:
if (counter > n):
return
yield a
a, b = b, a + b
counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
while True:
try:
print (next(f), end=" ")
except StopIteration:
sys.exit()
类似的产生斐波拉西数列,不用一开始就生成list,反正用户每次取,我都能给你返回一个值,给用户的感觉就像是在使用迭代器一样
所以生成器是一个返回迭代器的函数