您的位置:首页 > 编程语言 > Python开发

Python3.x 迭代器和生成器

2017-12-05 10:02 197 查看
#迭代器
#迭代器用于访问集合元素,它可以记住遍历的位置的对象
#迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束,迭代器只能往前不会后退
#迭代器两个基本方法:iter()和next()
#字符串,列表或元组对象都可用于创建迭代器
list = [1,2,3,4]
it = iter(list) #创建迭代器对象
print(next(it))
print(next(it))

#结果:
1
2

#迭代器对象可使用常规for语句进行遍历:
list = [1,2,3,4]
it = iter(list) #创建迭代器对象
for x in it:
print(x, end=" ")
#结果:
1 2 3 4

import sys #引入sys模块
list = [1,2,3,4]
it = iter(list) #创建迭代器对象
while True:
try:
print(next(it))
except StopIteration:
sys.exit()

#结果:
1
2
3
4

#生成器
#在python中,使用yield的函数被称为生成器(generator)
#跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器
#在调用生成器运行过程中,每次遇到yield时函数会暂停并保存当前所有的运行信息,返回yield的值。并在下一次执行next()
#方法时从当前位置进行运行
#以下实例使用yield实现斐波那契数列:
import sys
def fibonacci(n): #生成器函数 - 斐波那契
a, b, counter = 0, 1, 0
while True:
if(counter > n):
return
yield a
a, b = b, a+b
print('%d,%d' % (a,b))
counter += 1
f = fibonacci(10) #f是一个迭代器,由生成器返回生成

while True:
try:
print(next(f), end=" ")
except StopIteration:
sys.exit()

#结果
0 1,1
1 1,2
1 2,3
2 3,5
3 5,8
5 8,13
8 13,21
13 21,34
21 34,55
34 55,89
55 89,144

#什么情况下需要使用yield?
#一个函数f,f返回一个list,这个list是动态计算出来的(不管是数学上的计算还是逻辑上的读取格式化),并且这个list会很大(无论是固定很大还是随着输入参数的增大而增大)
#这个时候,我们希望每次调用这个函数并使用迭代器进行循环的时候,一个一个的得到每个list元素而不是直接得到一个完整的list来节省内存,这个时候yield就很有用
#以斐波那契函数为例,我们一般希望从n返回一个n个数的list
import sys
def fab(max):
n,a,b=0,0,1
L = []
while n < max:
L.append(b)
a,b=b,a+b
n=n+1
return L
#上面这个fab函数从参数max返回一个有max个元素的list,当这个max是一个很大的数的时候,会占用很多内存
#一般会用下面的方式使用:
f = iter(fab(1000))
while True:
try:
print(next(f), end=" ")
except StopIteration:
sys.exit()

#结果:
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986...
#这样做法实际上是先生成了一个1000个元素的list:f,然后我们再去使用这个f。
#现在,我们换一个方法:
#因为实际使用的是list的遍历,也就是list的迭代器。那么我们可以让这个函数fab每次只返回一个迭代器--一个计算结果,而不是一个完整的list:

import sys
def fab(max):
n,a,b=0,0,1
while n<max:
yield b
#print b
a, b=b,a+b
n=n+1
for x in fab(20):
print(x)

#结果
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765



参考网址
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息