返回顶部

08 python迭代器和生成器

python中的迭代协议

什么是迭代器?

迭代器是访问集合内部元素的一种方式,一般用于遍历数据
迭代器和用下标的访问方式不一样,也就是说迭代器是不能返回数据的,迭代器提供了一种惰性方式产生数据
可迭代实质上是由__iter__来实现的
迭代器必须要同时有__iter__和__next__魔法函数
1
2
3
4
5
from collections.abc import Iterable, Iterator
 
a = [1, 2]
print(isinstance(a, Iterable))
print(isinstance(a, Iterator))
输出结果如下

 

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

可迭代对象 内部实现了 __iter__方法 可以用于遍历

迭代器 内部实现了 __iter__和__next__方法 可以用于遍历和next()取值

把一个可迭代对象编程迭代器,可以使用iter(可迭代对象)

1
2
a = [1, 2]
iter_rator = iter(a)

 

自定义一个迭代器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class MyIterator:
    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 = MyIterator(["tom", "bob", "jane"])
 
 
    print(next(company))
    for item in company:
        print (item)

  

输出结果如下

生成器函数的使用

生成器函数,函数里只要有yield关键字

1
2
3
4
5
6
7
8
9
10
#生成器函数,函数里只要有yield关键字
def gen_func():
    yield 1
    yield 2
    yield 3
gen = gen_func()
 
print(next(gen))
for item in gen:
    print(item)  

输出结果如下

递归实现 斐波那契求值

1
2
3
4
5
6
7
8
def fib(index):
    if index <= 2:
        return 1
    else:
        return fib(index-1) + fib(index-2)
 
if __name__ == '__main__':
    print(fib(8))

输出结果如下

 

 生成器实现斐波那契

1
2
3
4
5
6
7
8
9
10
11
12
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__'
    gen_fib = gen_fib(10)
    for value in gen_fib:
        print(value)

  

打印结果如下

 生成器在UserList中的应用

 查看UserList的源码

from collections import UserList

可以看到每次遍历的时候都会通过yield返回一个值

 

生成器如何读取大文件

假如有一个500G的文件,我们想要读取它,如果它是一行一行的话我们可以使用for循环一行一行的读

这里的一个500G的文件是在一行,这时候我们可以用生成器来读取

input.text

1
Prior to beginning tutoring sessions{|}, I ask new students to fill{|} out a brief self-assessment{|} where they rate their{|} understanding of various Python concepts. Some topics ("control flow with if/else" or "defining and using functions") are understood by a majority of students before ever beginning tutoring. There are a handful of topics, however, that almost all{|} students report having no knowledge or very limited understanding of. Of these

 生成器读取大文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#500G, 特殊 一行
def myreadlines(f, newline):
  buf = ""  # 缓存,用来保存生成器一次返回的数据
  while True:
    while newline in buf:
      pos = buf.index(newline)
      yield buf[:pos]
      buf = buf[pos + len(newline):]  # 获取的是满足条件的一行+ {|}后面的内容
    chunk = f.read(4096)
 
    if not chunk:
      #说明已经读到了文件结尾
      yield buf
      break
    buf += chunk
 
with open("input.txt") as f:
    for line in myreadlines(f, "{|}"):
        print (line)

  

输出结果如下

 

posted @   Crazymagic  阅读(317)  评论(0编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示

目录导航