笔记:学习python中的总结(八)

python中的 迭代器和生成器
迭代器协议 是__iter__
迭代器是访问集合内元素的一种方式,一般是用来遍历数据的
for 是背后的迭代器在产生作用,
迭代器和以下标的访问方式不一样,迭代器是不能返回的,迭代器提供了一种惰性访问数据的方式
[]使用下标的访问方式,是使用__getitem__

from collections.abc import Iterable,Iterator
重点放在 Iterator 上

*****************************************************************************
class Iterable(metaclass=ABCMeta):

    __slots__ = ()

    @abstractmethod
    def __iter__(self):
        while False:
            yield None

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Iterable:
            return _check_methods(C, "__iter__")
        return NotImplemented
*****************************************************************************
class Iterator(Iterable):

    __slots__ = ()

    @abstractmethod
    def __next__(self):
        'Return the next item from the iterator. When exhausted, raise StopIteration'
        raise StopIteration

    def __iter__(self):
        return self

    @classmethod
    def __subclasshook__(cls, C):
        if cls is Iterator:
            return _check_methods(C, '__iter__', '__next__')
        return NotImplemented
*****************************************************************************
from collections.abc import Iterable,Iterator
a =  [1,2]
iter_rator = iter(a) #返回一个迭代器
print(isinstance(a,Iterator))
print(isinstance(iter_rator,Iterator))
print(isinstance(a,Iterable))
>> False
>> True
>> True
a是list ,list不是一个迭代器,但是list是可迭代的,迭代器不支持切片
自己定义可迭代的对象
from collections.abc import Iterator

class Company(object):
    def __init__(self,employee_list):
        self.employee = employee_list

    def __iter__(self):
        return MyIterator(self.employee)

    # def __getitem__(self, item):
    #     return self.employee[item]

class MyIterator(Iterator):
    def __init__(self,employee_list):
        self.iter_list = employee_list
        self.index = 0

    # def __iter__(self):
    #     return self

    def __next__(self):
        #真正返回迭代值的逻辑
        try:
            word = self.iter_list[self.index]
        except IndexError:
            raise StopIteration
        self.index += 1
        return word


if __name__ == "__main__":
    company = Company(["1","2","3"])
    my_itor = iter(company)
    # while True:
    #     try:
    #         print(next(my_itor))
    #     except StopIteration:
    #         pass

    #
    # next(my_itor)
    for item in company:
        print(item)
>> 1
>> 2
>> 3
生成器函数,函数里只要有yield关键字,这就是一个生成器函数,不是普通的函数了
生成器函数 返回的是 一个生成器对象
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
def gen_func():
    yield 1

def func():
    return 1

if __name__ == "__main__":
    #生成器对象,在python编译字节码的时候就产生了
    gen = gen_func()
    re = func()
    pass"pass" 处进行debug 的结果:
gen = {generator}<generator object gen_func at 0x106dc7570>
re = {int} 1
对代码进行改进: #生成器对象也是实现迭代器协议的

if __name__ == "__main__":
    gen = gen_func()
    for value in gen:
        print(value)
>> 1 

yield 是 连续返回,实现的是迭代器协议,非常精妙的设计,惰性求值,
或者称为延迟求值,提供可能 

def fib(index):
    if index <= 2:
        return 1
    else:
        return fib(index-1)+fib(index-2)

print(fib(10))

def fib1(index):
    re_list = []
    n,a,b =0,0,1
    while n<index:
        re_list.append(b)
        a,b = b,a+b
        n = n+1
    return re_list

print(fib1(10)) 

def gen_fib(index):
    n,a,b =0,0,1
    while n<index:
        yield b
        a,b = b,a+b
        n = n+1
for data in gen_fib(10):
    print(data)

>>  55
>>  [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] 
>>  1
>>  2
>>  3
>>  5
>>  8
>>  13
>>  21
>>  34
>>  55
生成器的原理
python的解释器是由C语言来写的,会用一个叫做 pyEval_EvalFramEx(C函数)去执行foo函数,首先会创建一个栈帧(stack_frame),栈帧对象,字节码对象,

猜你喜欢

转载自blog.csdn.net/sinat_33588424/article/details/80918486