python迭代器和生成器

迭代器

可迭代对象

很多容器都是可迭代对象,此外还有更多的对象同意也是可迭代对象,但凡是可以返回一个迭代器的对象都可称之为可迭代对象。

迭代器

1.提供了一个方法,可以不断获取对象里的数据
2.用户不需要关系内部细节,只需要通过这个特点接口获取数据
3.当没有数据再次调用时,会得到一个停止标记
4.不能随机访问集合中的某个值,只能从头到尾依次访问
5.访问到一半时不能往回退
6.便于循环比较大的数据集合,节省内存

比如在python中的列表和字典容器,要想获得他里面的数据,就需要借助for…in的语法,其实for…in就是一个隐式迭代器的使用方法。
其实迭代器就是一个带状态的对象,它能在你调用next()方法时返回容器中的下一个值。

python迭代器的使用方法

iter()方法,返回一个迭代器
itertools模块函数返回的都是迭代器对象

在迭代器中会定义一个叫做__next__方法,他提供获取数据的接口;
在python中定义个next()的内置函数,专门调用迭代器的__next__方法;
一旦没有数据后,再次访问时,会受到StopIteration的异常

import itertools as it

str1 = iter('abcd')
print(next(str1))
co = it.count(10, 10)  # 无限迭代器
print(next(co))
print(next(co))
print(next(co))
str2 = it.cycle('abcd')  # 通过有限的元素,生成无限的迭代器
print(next(str2))
print(next(str2))
print(next(str2))
print(next(str2))
print(next(str2))

co1 = it.islice(co, 0, 1)  # 从无限迭代器里面,截取有限的数据
print(next(co1))

判断一个对象是否可以迭代

使用isinstance()判断一个对象是否是iterable对象,返回值是布尔值

from collections import Iterable

print(isinstance(123, Iterable))  # False
print(isinstance('123', Iterable))  # True

自定义迭代器

任何实现了__iter__和__next__()方法的对象都是迭代器,__iter__返回迭代器自身,__next__返回容器的下一个值.

可迭代对象:只要实现了__iter__方法,就是可迭代对象.
from collections import Iterable


class People(object):
    """
    实现 __iter__  实例为可迭代对象
    """

    def __iter__(self):
        return self


stu = People()

print(isinstance(stu, Iterable))
迭代器:获取容器中的数据,只要实现了__next__方法,就称之为迭代器.next()函数的本质就是调用对象的__next__()方法,实现了__next__()方法的对象,就是迭代器
class Man(object):
    """
    实现 __next__()
    实例为 迭代器
    """

    def __init__(self):
        self.__age = 18

    def __next__(self):
        self.__age += 10
        return self.__age


man = Man()
print(next(man))
print(next(man))
print(next(man))

练习:

使用迭代器,来实现 斐波那契数列

class Fib(object):
    def __init__(self):
        self.__now = 1
        self.__prev = 0

    def __iter__(self):
        return self

    def __next__(self):
        # 迭代的过程 把变量拿来使用,并且更新
        value = self.__now
        self.__now = self.__now + self.__prev
        self.__prev = value
        return value


fib = Fib()
print(next(fib))
print(next(fib))
print(next(fib))
print(next(fib))
print(next(fib))
print(next(fib))

生成器

利用迭代器,我们可以不断的获取数据.但是在实际开发中,我们有时候希望数据一开始不存放在内存上,而是遵循某种规律,在用户需要的时候提供给用户.这时就需要生成器,它不仅具备迭代器的能力,而且他是使用时再分配,而不是事先分配空间.

列表生成器

要创建一个生成器有很多种方法,其中最简单的就是把一个列表生成式[]改成()

li1 = [v*5 for v in range(10000)]
print(li1)
li2 = (v*5 for v in range(10000))
print(next(li2))
print(next(li2))

这种方式,被称之为列表生成器,它也是迭代器,只是书写起来会非常清晰.但列表生成器只能做一些简单的逻辑.

函数生成器

当推算算法比较复杂,用列表生成器无法实现其逻辑时,可以使用函数生成器来实现.它的语法很简单,就是将普通函数的return替换为yield
yield的意思不是返回,而是抛出后面的变量值,然后保存当前的函数状态,等待next的操作.一旦函数内部使用yield,函数名被调用是,函数的代码不会立即执行,会返回一个生成器,使用next()时,函数代码立即执行,直到遇到yield代码停止

def gen():
    i = 1
    while i <= 10:
        return i  # 函数执行return 会返回值,并停止代码的执行
        i += 1


print(gen())


def gener():
    i = 1
    while i <= 3:
        print('我是yield前面的')
        yield i  # 使用 yield 会返回值,并暂停代码的执行:通过 next()调用
        print('我是yield后面的')
        i += 1


res = gener()
print(next(res))
print(next(res))

练习

使用生成器来实现斐波拉契

def fib():
    now = 1
    prev = 0
    while True:
        value = now
        now = prev + now
        prev = value
        yield value


f = fib()
for v in f:
    print(v)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值