python生成器介绍

生成器

原始代码

ans_file_paths = [path for path in file_paths if any(id_ in path for id_ in ids_set)]

修改后代码

def file_generator(root_dir, ids_set):
    """生成器:用于生成符合条件的文件路径"""
    file_pattern = os.path.join(root_dir, '*csv')
    file_paths = glob(file_pattern)
    for path in file_paths:
        if any(id_ in path for id_ in ids_set):
            yield path

原始代码解释:

  1. 列表推导式:这段代码使用了 Python 中的列表推导式(list comprehension),是一种简洁的方式来生成一个列表。
  2. 条件筛选:它从 file_paths 列表中筛选出符合条件的文件路径。具体来说,它会检查 ids_set 中的每个 id_ 是否出现在路径 path 中。
  3. 结果:最终,ans_file_paths 将包含所有符合条件的文件路径。

修改后解释:

  1. 定义了一个生成器函数:修改后的代码将原来的列表推导式转换成了一个生成器函数 file_generator。生成器是一种特殊的迭代器,允许你逐个生成值,而不是一次性生成所有值。

  2. 使用 yield 关键字:在 file_generator 函数中,使用了 yield 关键字。当函数执行到 yield 时,它会返回一个值并暂停执行,以后再调用时会从暂停的地方继续执行。这意味着生成器不会一次性将所有结果都计算出来,而是按需生成。

  3. 内存效率:使用生成器的一个主要好处是内存效率。原始代码会一次性创建一个包含所有符合条件路径的列表,这在处理大量文件路径时可能会消耗大量内存。而生成器则只会在需要时生成一个路径,这样可以节省内存。

  4. 可读性和可重用性:将代码封装在函数中提高了可读性和可重用性。你可以多次调用 file_generator,并在不同的地方使用它,而不必每次都写一遍筛选逻辑。

总结

  • 原始代码:使用列表推导式一次性生成所有符合条件的文件路径,可能会占用较多内存。
  • 修改后代码:使用生成器按需生成文件路径,节省内存,提高了代码的可读性和可重用性。

案例1

原代码:

def main():
    dir = r'F:\02-data\test'
    file_paths = glob(os.path.join(dir, f'*.csv'))
    for file_path in file_paths:
        data = pd.read_csv(file_path, encoding='gbk')
        out_name = re.split('[\\\\, .]', file_path)[-2]
        data.to_csv(r'F:\02-data\test\无加密\{}.txt'.format(out_name), index=False, encoding='utf8')
    print('ok')

修改后代码:

def file_generator(dir):
    """生成器,用于逐个读取CSV文件路径"""
    file_paths = glob(os.path.join(dir, '*.csv'))
    for file_path in file_paths:
        yield file_path
def main():
    dir = r'F:\02-data\test'
    output_dir = r'F:\02-data\test\无加密'
    # 使用生成器
    for file_path in file_generator(dir):
        data = pd.read_csv(file_path, encoding='gbk')
        out_name = re.split('[\\\\, .]', file_path)[-2]
        data.to_csv(os.path.join(output_dir, f'{out_name}.txt'), index=False, encoding='utf8')

增加并行计算:

import os
import re
import pandas as pd
from glob import glob
from concurrent.futures import ProcessPoolExecutor
def process_file(file_path):
    """处理单个文件的函数"""
    data = pd.read_csv(file_path, encoding='gbk')
    out_name = re.split('[\\\\, .]', file_path)[-2]
    output_path = os.path.join(r'F:\02-data\test\无加密', f'{out_name}.txt')
    data.to_csv(output_path, index=False, encoding='utf8')
def file_generator(dir):
    """生成器,用于逐个读取CSV文件路径"""
    file_paths = glob(os.path.join(dir, '*.csv'))
    for file_path in file_paths:
        yield file_path
def main():
    dir = r'F:\02-data\test'
    num_workers = 4  # 指定进程数量,可以根据需要进行调整

    # 使用ProcessPoolExecutor进行并行处理
    with ProcessPoolExecutor(max_workers=num_workers) as executor:
        executor.map(process_file, file_generator(dir))  # 直接使用生成器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值