一、迭代器
(一)可迭代对象
- 迭代:能被for in 循环取值的过程叫做迭代。字典是无序的。
- 可迭代对象:凡是能用for in 遍历或者说迭代的类型都是可迭代对象。
- 如何判断一个对象是可迭代对象
from collections import Iterable
# 1、列表,元祖,字典,字符串,集合,迭代器都是可迭代对象,
res = isinstance([], Iterable)
print(res) # True
res = isinstance({}, Iterable)
print(res) # True
res = isinstance(123, Iterable)
print(res) # Flase
res = isinstance(iter([]), Iterable)
print(res)
- 可迭代对象的本质
在迭代一个可迭代对象的时候,实际上就是先获取该对象提供的一个迭代器,然后通过这个迭代器来依次获取对象中的每一个数据
(二)iter()函数和next()函数
# 1、如果把可迭代对象放入iter()中,那么就生成了一个迭代器
# 2、并且iter()里面只能放入可迭代对象或者迭代器,最终为迭代器。
# 3、next()只能接收迭代器和生成器
list1 = [1, 2, 3, 4, 5, 6]
b = iter(list1) # 迭代器
print(next(b))
(三)迭代器
- 如何判断一个对象是否为迭代器
from collections import Iterator
# iter(可迭代对象)都属于迭代器。
# 生成器都属于迭代器
# 迭代器都是可迭代对象
# 可迭代对象不一定是迭代器
res = isinstance([], Iterator)
print(res) # False
res = isinstance((i for i in range(10)), Iterator)
print(res) # True
res = isinstance(iter([]), Iterator)
print(res) # True
- 自定义迭代器
# 定义可迭代对象
class Mylist(object):
def __init__(self):
self.items = list()
def append_item(self, item):
self.items.append(item)
# 添加一个__iter__方法表示可迭代对象
# 迭代对象的本质是通过获取迭代对象的迭代器来获取下一个值得
def __iter__(self):
myIterator = MyIterator(self.items)
return myIterator
# 如果一个类型里有__iter__()和__next__()方法叫做迭代器。
# 迭代器就是记录当前位置和获取当前位置获取的值
class MyIterator(object):
def __init__(self, items):
self.items = items
self.current_index = 0
def __iter__(self):
return self
def __next__(self):
if self.current_index < len(self.items):
self.current_index += 1
return self.items[self.current_index - 1]
else:
raise StopIteration
mylist = Mylist()
mylist.append_item("小红")
mylist.append_item("小明")
for value in mylist:
print(value)
- 用迭代器完成斐波那契数列
# 完成斐波那契数列
class Fbnq(object):
def __init__(self, num):
# 记录生成的个数
self.num = num
self.a = 0
self.b = 1
# 记录当前的索引
self.current_index = 0
def __iter__(self):
return self
def __next__(self):
if self.current_index < self.num:
result = self.a
self.a, self.b = self.b, self.a + self.b
self.current_index += 1
return result
else:
raise StopIteration
f = Fbnq(5)
print(next(f))
# for i in f:
# print(i)
二、生成器
(一)用生成器完成斐波那契数列
# 如果函数里出现yield表示一个生成器
# 如果代码执行到yield那么先把结果返回,然后代码暂停,
# 下次外界启动生成器在之前暂停的位置继续向下执行。
# ①yield每次执行代码都会暂停。知道在此启动生成器
# ②如果用return只能返回一次
# ③而用yield能够返回多次的结果
def fbnq(n):
a = 0
b = 1
for i in range(n):
a, b = b, a+b
yield a
f = fbnq(5)
print(next(f))
for i in f:
print(i)
(二)生成器中的send()的用法
def fbnq(n):
a = 0
b = 1
for i in range(n):
a, b = b, a+b
params = yield a
print(params)
f = fbnq(5)
# 如果一开始发送haha那么没有变量去接收他,所以报错
# print(f.send("haha"))
# 第一个值可以用先用next完成第一次启动,或者用send(None)去接收
print(f.send(None))
print(f.send("哈哈"))
(二)创建生成器的方法
- 只需要把列表的【】改为()
generator = (x * 2 for x in range(10))
print(next(generator))
用yield
- 使用了yield关键字的函数不再是函数,而是生成器。(使用了yield的函数就是生成器)
- yield关键字有两点作用:
- 保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起
- 将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用
- 可以使用next()函数让生成器从断点处继续执行,即唤醒生成器(函数)
- Python3中的生成器可以使用return返回最终运行的返回值,而Python2中的生成器不允许使用return返回一个返回值(即可以使用return从生成器中退出,但return后不能有任何表达式)。