python学习-生成器 迭代器

一、迭代器

(一)可迭代对象

  • 迭代:能被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后不能有任何表达式)。

猜你喜欢

转载自blog.csdn.net/zhangmoyan9527/article/details/81836222
今日推荐