• python高级(02)--生成器和迭代器


    python高级(02)--生成器和迭代器

    python的迭代协议

    # 什么是迭代协议
    # 迭代器是什么? 迭代器是访问集合内元素的一种方式, 一般用来遍历数据
    # 迭代器和以下标的访问方式不一样, 迭代器是不能返回的, 迭代器提供了一种惰性方式数据的方式
    # [] list , __iter__
    
    
    from collections.abc import Iterable, Iterator
    
    
    a = [1, 2]
    print(isinstance(a, Iterable))
    print(isinstance(a, Iterator))
    to_iterator = iter(a)
    print(isinstance(to_iterator, Iterator))
    

    什么是迭代器和可迭代对象

    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 __next__(self):
            # 真正返回迭代值的逻辑
            try:
                word = self.iter_list[self.index]
            except IndexError:
                raise StopIteration
            self.index += 1
            return word
    
    
    if __name__ == "__main__":
        company = Company(["tom", "bob", "jane"])
        my_itor = iter(company)
        # while True:
        #     try:
        #         print (next(my_itor))
        #     except StopIteration:
        #         pass
    
        # next(my_itor)
        for item in company:
            print(item)
    

    生成器的使用

    # 生成器函数,函数里只要有yield关键字
    def gen_func():
        yield 1
        yield 2
        yield 3
    
    
    def fib(index):
        if index <= 2:
            return 1
        else:
            return fib(index - 1) + fib(index - 2)
    
    
    def fib2(index):
        re_list = []
        n, a, b = 0, 0, 1
    
        while n < index:
            re_list.append(b)
            a, b = b, a + b
            n += 1
        return re_list
    
    
    def gen_fib(index):
        n, a, b = 0, 0, 1
    
        while n < index:
            yield b
            a, b = b, a + b
            n += 1
    
    
    if __name__ == "__main__":
        # 生成器对象, python编译字节码的时候就产生了
        gen = gen_func()
        for val in gen:
            print(val)
    
        print(fib(10))
        print(fib2(10))
        g_fib = gen_fib(10)
        for i in g_fib:
            print(i)
    
    

    生成器的原理

    生成器

    生成器2

    # 1.python中函数的工作原理
    """
    """
    import inspect
    
    frame = None
    
    
    def foo():
        bar()
    
    
    def bar():
        global frame
        frame = inspect.currentframe()
    
    # python.exe会用一个叫做 PyEval_EvalFramEx(c函数)去执行foo函数, 首先会创建一个栈帧(stack frame)
    """
    python一切皆对象,栈帧对象, 字节码对象
    当foo调用子函数 bar, 又会创建一个栈帧
    所有的栈帧都是分配在堆内存上,这就决定了栈帧可以独立于调用者存在
    """
    # import dis
    # print(dis.dis(foo))
    
    foo()
    print(frame.f_code.co_name)
    caller_frame = frame.f_back
    print(caller_frame.f_code.co_name)
    
    
    def gen_func():
        yield 1
        name = 'suki'
        sex = 'female'
        yield 2
        age = 30
        return 'snoopy'
    
    
    import dis
    gen = gen_func()
    print(dis.dis(gen), '
    ')
    
    print(gen.gi_frame.f_lasti)
    print(gen.gi_frame.f_locals)
    
    next(gen)
    print(gen.gi_frame.f_lasti)
    print(gen.gi_frame.f_locals)
    
    next(gen)
    print(gen.gi_frame.f_lasti)
    print(gen.gi_frame.f_locals)
    

    通过UserList来看生成器的应用

    class Company:
        def __getitem__(self, item):
            pass
    
    
    from collections import UserList
    

    生成器实现大文件读取

    # 500G, 特殊 一行
    
    
    def my_read_lines(f, new_line):
        buf = ""
        while True:
            while new_line in buf:
                pos = buf.index(new_line)
                yield buf[:pos]
                buf = buf[pos + len(new_line):]
            chunk = f.read(4096)
    
            if not chunk:
                yield buf
                break
            buf += chunk
    
    
    with open('input.txt') as f:
        for line in my_read_lines(f, '{|}'):  # {|}为分隔符
            print(line)
    
  • 相关阅读:
    Apache Spark 内存管理详解
    内存映射文件原理探索
    十大Intellij IDEA快捷键
    excel比较筛选两列不一样的数据
    利用Phoenix为HBase创建二级索引
    Avoid RegionServer Hotspotting Despite Sequential Keys
    Phoenix表和索引分区数对插入和查询性能的影响
    P5462 X龙珠
    P3944 肮脏的牧师
    P1351 联合权值
  • 原文地址:https://www.cnblogs.com/pankypan/p/13663684.html
Copyright © 2020-2023  润新知