#! /usr/bin/python
# -*- coding: utf-8 -*-
# 迭代器
'''
迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。
迭代器有两个基本的方法:iter() 和 next()。
'''
'''
字符串,列表或元组对象都可用于创建迭代器
'''
list = [1, 2, 3, 4]
it = iter(list)
print (next(it))
print (next(it))
print (next(it))
print ("\n")
'''
迭代器对象可以使用常规for语句进行遍历
'''
it = iter([1, 2, 3, 4, 5])
for x in it:
print (x)
print ("\n")
# 使用next()迭代
import sys
list = [1, 2, 3, 4, 5, 6]
it = iter(list)
# while True:
# try:
# print (next(it))
# except StopIteration:
# sys.exit()
print ("\n")
# 创建迭代器
'''
把一个类作为一个迭代器使用需要在类中实现两个方法 __iter__() 与 __next__()
__iter__() 方法返回一个特殊的迭代器对象, 这个迭代器对象实现了 __next__() 方法并
通过 StopIteration 异常标识迭代的完成。
__next__() 方法(Python 2 里是 next())会返回下一个迭代器对象
'''
class myNumbers:
def __iter__(self):
self.a = 1
return self
def next(self):
x = self.a
self.a += 1
return x
myclass = myNumbers()
myiter = iter(myclass)
print (next(myiter))
print (next(myiter))
print (next(myiter))
# StopIteration
'''
StopIteration 异常用于标识迭代的完成,防止出现无限循环的情况,
在 __next__() 方法中我们可以设置在完成指定循环次数后触发 StopIteration 异常来结束迭代
'''
class myNumbers2:
def __iter__(self):
self.a = 1
return self
def next(self):
if self.a <= 20:
x = self.a
self.a += 1
return x
else:
raise StopIteration
myclass = myNumbers2()
it = iter(myclass)
for x in it:
print (x)
print ("\n")
# 生成器
'''
在 Python 中,使用了 yield 的函数被称为生成器(generator)。
跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值,
并在下一次执行 next() 方法时从当前位置继续运行。
调用一个生成器函数,返回的是一个迭代器对象
'''
import sys
def fibonacci(n): # 生成器函数 - 斐波那契
a, b, counter = 0, 1, 0
while True:
if counter > n:
return
print ("AAA")
yield a
a, b = b, a+b
counter += 1
f = fibonacci(10)
for x in f:
print (x)
print ("\n")
# while True:
# try:
# print (next(f))
# except StopIteration:
# sys.exit()
# 对比有没有yield的情况
# 使用 yield
def f1(n):
a, b, counter = 0, 1, 0
while True:
if (counter > n):
return
yield a
a, b = b, a + b
counter += 1
print ('%d %d'%(a, b))
f = f1(10)
for x in f:
print (x)
print ("\n")
# 不适用yeild
def f2(n):
a, b, counter = 0, 1, 0
L = []
while True:
if counter > n:
return
a, b = b, a+b
counter += 1
print ("%d %d"%(a, b))
f = f2(10)
# while True:
# try:
# print (next(f))
# except :
# sys.exit()
l = [i for i in range(0, 15)]
print (l)
m = (i for i in range(0, 15))
print (m)
'''
一个函数 f,f 返回一个 list,
这个 list 是动态计算出来的(不管是数学上的计算还是逻辑上的),
并且这个 list 会很大(无论是固定很大还是随着输入参数的增大而增大),
这个时候,我们希望每次调用这个函数并使用迭代器进行循环的时候一个一个的得到每个 list 元素
而不是直接得到一个完整的 list 来节省内存,这个时候 yield 就很有用
'''
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 很大的时候,会非常的占用内存
'''
def fab2(max):
n, a, b = 0, 0, 1
while n < max:
yield b
# print b
a, b = b, a + b
n = n + 1
'''
这样,我们每次调用fab函数,比如这样:
for x in fab(1000):
print(x)
或者 next 函数之类的,实际上的运行方式是每次的调用都在 yield 处中断并返回一个结果,
然后再次调用的时候再恢复中断继续运行
'''
def get():
m = 0
n = 2
l = ['s', 1, 3]
k = {1:2, 2:2}
p = ('2', 's', 'y')
while True:
m += 1
yield m
yield m, n, l, k, p
it = get()
print (next(it)) #1
print (next(it)) # (1, 2, ['s', 1, 3], {1: 2, 2: 2}, ('2', 's', 'y'))
print (next(it)) #2
print (type(next(it))) # <type 'tuple'>
print(type(next(it))) # <type 'int'>
Python3 迭代器和生成器
©著作权归作者所有,转载或内容合作请联系作者
- 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
- 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
- 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...