page contents

Python生成器与迭代器深度解析:内存高效的数据流处理编程模式

还记得几年前那个让我彻夜难眠的项目吗。需要处理一个50GB的日志文件 结果用传统的文件读取方式 内存直接爆了 服务器差点宕机。那时候我还是个Python小白 完全不知道生成器这个神器的存在。后来才明白 这就是数据流处理的经典场景啊。

attachments-2025-07-Dr4oyIbJ68818ab53d9d7.jpg

还记得几年前那个让我彻夜难眠的项目吗。需要处理一个50GB的日志文件 结果用传统的文件读取方式 内存直接爆了 服务器差点宕机。那时候我还是个Python小白 完全不知道生成器这个神器的存在。后来才明白 这就是数据流处理的经典场景啊。

01迭代器其实就像是一个智能的书签。你不需要把整本书都记在脑子里 只要知道当前读到哪一页就行了。

每次调用next()方法 就翻到下一页。简单粗暴。

# 自定义迭代器实现

classNumberIterator:

  def __init__(self, max_num):

    self.max_num = max_num

    self.current =0

  def __iter__(self):

    return self

  def __next__(self):

    if self.current <self.max_num:

      self.current +=1

      return self.current

    else:

      raise StopIteration

# 使用方式

numbers =NumberIterator(5)

for num in numbers:

print(num)# 输出 1 2 3 4 5

但是写起来真的很麻烦啊。

02生成器就不一样了 简直是懒人福音。

用yield关键字 函数就自动变成了生成器 不需要手动实现那些复杂的协议。

def simple_generator(n):

  """简单生成器示例"""

  for i in range(n):

    print(f"生成数字: {i}")

    yield i  # 关键就在这里

    print(f"数字 {i} 已被消费")

# 创建生成器对象

gen = simple_generator(3)

# 逐个获取值

print(next(gen))# 生成数字: 0, 返回 0, 数字 0 已被消费

print(next(gen))# 生成数字: 1, 返回 1, 数字 1 已被消费

你会发现 每次调用next()函数都会从上次暂停的地方继续执行。这就是生成器的核心魅力。

暂停和恢复 就像视频播放器一样。

03在实际项目中 我最常用生成器来处理大文件。

比如那个50GB的日志文件 用生成器的话 内存占用几乎可以忽略不计。

def read_large_file(file_path):

  """大文件逐行读取生成器"""

  with open(file_path,'r', encoding='utf-8')as file:

    for line in file:

      # 可以在这里做一些预处理

      cleaned_line = line.strip()

      if cleaned_line:# 跳过空行

        yield cleaned_line

def process_log_data(file_path):

  """处理日志数据的业务逻辑"""

  error_count =0

  for line in read_large_file(file_path):

    if'ERROR'in line:

      error_count +=1

      # 这里可以做错误分析

      print(f"发现错误: {line[:100]}")# 只显示前100字符

  return error_count

# 使用方式

# total_errors = process_log_data('huge_log.txt')

这样写的好处是什么呢 内存使用量始终保持在很低的水平 不管文件多大。

04生成器表达式更是简洁到爆炸。

就像列表推导式的懒加载版本 用圆括号包起来就行了。

# 列表推导式 - 立即创建所有元素

squares_list =[x**2for x in range(1000000)]# 占用大量内存

# 生成器表达式 - 按需生成

squares_gen =(x**2for x in range(1000000))# 几乎不占内存

# 实际使用场景

def find_large_squares(limit):

  """找出大于某个值的平方数"""

  squares =(x**2for x in range(10000))

  return[sq for sq in squares if sq > limit]

result = find_large_squares(50000)

print(f"找到 {len(result)} 个符合条件的平方数")

当你需要处理大量数据但只关心其中一部分时 生成器表达式就是最佳选择。

节省内存又提升性能。

05有个经常踩的坑需要提醒一下。

生成器只能迭代一次 用完就没了 就像一次性筷子。

def demo_generator():

  for i in range(3):

    yield i

gen = demo_generator()

# 第一次迭代

list1 = list(gen)# [0, 1, 2]

# 第二次迭代

list2 = list(gen)# [] 空列表!

print(f"第一次: {list1}")

print(f"第二次: {list2}")

如果需要多次使用 要么重新创建生成器 要么把结果先存起来。

另外 生成器和协程的结合也很有意思 可以实现更复杂的异步数据处理流程。但那就是另一个话题了。

总的来说 掌握生成器和迭代器真的能让你的Python代码更加优雅高效。特别是在处理大数据集的时候 这些技巧能救你一命。

试试在下个项目中用起来吧 你会爱上这种编程方式的。

更多相关技术内容咨询欢迎前往并持续关注好学星城论坛了解详情。

想高效系统的学习Python编程语言,推荐大家关注一个微信公众号:Python编程学习圈。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Python入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2022-05-rLS4AIF8628ee5f3b7e12.jpg

  • 发表于 2025-07-24 09:22
  • 阅读 ( 34 )
  • 分类:Python开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1335 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 2172 文章
  3. Pack 1335 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章