[python知识巩固]迭代器和生成器
1. 迭代器是什么
迭代器功能上和list遍历没有区别,也就是遍历一个list,不过一次只返回一个元素。也就是说在我们没有明确要求他获取下一个元素之前,是不知道下个元素是什么的。
迭代器的工作原理被计算机科学称之为惰性求值。由于迭代器的惰性属性,是处理无穷大问题的好方法,即可以永远迭代可迭代对象。
在python中迭代器函数为iter(),是一种特殊的函数,它能使我们实现迭代器。
1.1使用迭代器循环和list循环的区别
使用到for循环时,迭代器返回的是一个对象,而list返回的是一个列表,在处理大量数据的时候,list会消耗大量内存,而迭代器不会。
1.2 可迭代对象
在python中,不是所有对象都是可以迭代的,所以在使用迭代器之前必须知道哪些对象是可以迭代的。在我们常用的数据类型中,有几个数据类型是可以被for循环的,而for循环就是可迭代对象的循环,这就说明了如:字符串、列表、字典、集合、元祖是属于可以迭代的对象。当然,文件对象也是可迭代对象
PS:可迭代对象就是在内置方法中含有__iter__的就是可迭代对象。
lists = [1,2,3,4,5]
print(lists.__iter__())
1.3 迭代器对象
迭代器对象从集合的第一个元素开始访问,知道所有的元素被访问完结束。迭代器对象的值一旦被访问,就会“死亡”,不能进行取值了,想要重新取值的话,就必须重新再迭代一次。
1.3 迭代器的使用
·迭代器有两个基本的方法: iter() 和 next()
lists = [1,2,3,4,5]
it = iter(lists)
print(next(it))
>>> 1
print(next(it))
>>> 2
· 迭代器对象可以通过for循环进行遍历。
lists = [1,2,3,4,5]
it = iter(lists)
for t in it:
print(t)
>>> 1
2
3
4
5
·可以使用next()函数遍历
import sys
lists = [1,2,3,4,5]
it = iter(lists)
while True:
try:
print(next(it))
except StopIteration:
sys.exit()
·创建迭代器
class IterNumbers():
def __iter__(self):
self.a = 1
return self
def __next__(self):
x = self.a
self.a += 1
return x
num = IterNumbers()
itnum = iter(num)
print(next(itnum))
print(next(itnum))
print(next(itnum))
print(next(itnum))
>>>1
2
3
4
· 加上异常抛出
class IterNumbers():
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
num = IterNumbers()
itnum = iter(num)
for it in itnum:
print(it)
>>>1
2
3
4
....
20
1.4 迭代器的优点和缺点
·优点:
- 为序列和非序列提供了一个同一的迭代取值方式。
- 惰性计算:不管迭代器对象有多大,同一时刻只有一行数据存在,不会占用过大内存。
·缺点:
- 并不能知道这个迭代器的长度(不过有第三方库可以解决这个问题)
- 取值是一次性的,不能获取上一个元素,除非我们重新迭代一次。
2. 生成器是什么
生成器就是自定义的迭代器
生成器本省就是迭代器,但是和迭代器不同的是,生成器多了一个yield关键字。
yield关键字:
- yield可以暂停函数的运行
- yield 可以返回值,类似于return
2.1 生成器的使用
·yield 返回值
def fun():
print(1)
yield 1
print(2)
yield 2
a = fun()
next(a) # 打印1 返回1
>>> 1
next(a) # 打印2 返回2
>>> 2
next(a) # 代码执行完毕抛出StopIteration异常
·yield不但可以返回值,还可以接收值
def foo():
print("生成器开始运行了。")
while True:
x = yield 123 # yield表达式
print(f"{x}在运行着")
g = foo() # 创造一个生成器对象
g.send(None) # 等同于next(g) 第一步必须向生成器传一个空值启动生成器。(必须传)
a = g.send(5) # 将5给变量值x,然后开始运行,直到下一个yield,然后返回yield之后的值
>>>生成器开始运行了。
5在运行着
Reference:
- https://www.runoob.com/python3/python3-iterator-generator.html
- https://www.cnblogs.com/liqianxin/p/12559863.html#%E4%B8%80%E3%80%81%E8%BF%AD%E4%BB%A3%E5%99%A8