zoukankan      html  css  js  c++  java
  • 20190220 可迭代对象、迭代器、生成器

    可迭代对象、迭代器、生成器

    说明

    • 可迭代对象包含迭代器。

    • 如果一个对象拥有__iter__方法,是可迭代对象(类似接口);如果一个对象拥有__next__方法,是迭代器(类似接口的实现类)。

    • 定义可迭代对象,必须实现__iter__方法;定义迭代器,必须实现__iter__和__next__方法。

    • 具有yield关键字的函数都是生成器

    自定义一个迭代器

    
    class MyIterable:
    
    
    
        def __iter__(self):
    
            return self
    
    
    
        def __init__(self, lst):
    
            self.lst = lst
    
            self.index = 0
    
    
    
        def __next__(self):
    
            try:
    
                ret = self.lst[self.index]
    
                self.index += 1
    
            except IndexError:
    
                raise StopIteration
    
    
    
            return ret
    
    
    
    
    
    if __name__ == '__main__':
    
        li = MyIterable([1, 2, 3, 5])
    
        for i in li:
    
            print(i)
    
    

    自定义一个生成器和一个普通函数的区别

    
    # 一个普通的函数
    
    def fun():
    
        return 1 # return关键字在这里只能定义一个
    
    
    
    
    
    # 只要函数中有yield关键字就是生成器
    
    def gen_fun():
    
        yield 1
    
        yield 2
    
        yield 3 # 但是yield和return不同可以定义多个
    
    
    
    
    
    if __name__ == '__main__':
    
        # python编译字节码的时候,会根据yield关键字认定这个函数是生成器。
    
        # 然把这个函数转换成一个生成器,这个过程完全是python帮助我们进行的。
    
        gen = gen_fun() # <generator object gen_fun at 0x03C7DC30>
    
        ret = fun() # 1
    
    
    
        # gen_fun()执行,返回了生成器对象
    
        # fun()执行,返回了1
    
    
    
        # 遍历生成器
    
        for v in gen:
    
            print(v) # 1 2 3
    
    

    使用生成器写一个斐波那契额数列函数

    
    # 使用生成器技术写一个斐波那契数列函数
    
    def gen_fib(index):
    
        n, a, b = 0, 0, 1
    
    
    
        while index > n:
    
            yield b
    
            a, b = b, a + b
    
            n += 1
    
    
    
    
    
    if __name__ == '__main__':
    
        for i in gen_fib(1000000): # 每一位的数据都是动态生成的,非常节省内存资源
    
            print(i)
    
    

    使用生成器读写大文件

    
    def read_file(fp, spl_str):
    
        """
    
        读取大文件
    
        :param fp: 文件读写句柄
    
        :param spl_str: 每一行的分隔符
    
        """
    
        str_buf = ''
    
        spl_len = len(spl_str)
    
    
    
        while 1:
    
            # 缓存中找分隔符
    
            while spl_str in str_buf:
    
                # 找到分隔符位置,用来切片字符串
    
                index = str_buf.index(spl_str)
    
                # yield出切片后的字符串
    
                yield str_buf[:index]
    
                # 将分隔符后面的有效字符串缓存
    
                str_buf = str_buf[index + spl_len:]
    
    
    
            # 读取信息
    
            chunk = fp.read(4096 * 10)
    
            # 处理读到数据
    
            if chunk:
    
                str_buf += chunk
    
            # 处理剩余数据
    
            else:
    
                yield str_buf
    
                break
    
    
    
    
    
    if __name__ == '__main__':
    
        with open('data', 'r') as file:
    
            for con in read_file(file, '{|}'):
    
                print(con)
    
    
  • 相关阅读:
    malloc和new的区别
    Http协议解析
    Linux基础命令-history
    Linux基础命令-last
    Linux基础命令-who
    Linux基础命令-free
    Linux基础命令-uptime
    Linux基础命令-uname
    Linux基础命令-ifconfig
    Linux基础命令-killall
  • 原文地址:https://www.cnblogs.com/gengwenhao/p/10699608.html
Copyright © 2011-2022 走看看