You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取yield返回的索引?解决生成器不可下标访问错误

解决生成器无法下标访问的TypeError问题

这个错误的根源很明确:你调用iter_commit(strSiteMap)[0]和[1]时,试图把生成器对象当成列表/序列来取下标,但生成器是迭代器的一种,它只能通过迭代来逐个获取元素,不支持直接用[]访问特定位置的元素。

你的需求拆解

你想要把iter_commit生成的每一组(index, schema),分别作为Parse函数的RoWnum和Link参数,用线程池批量处理。那正确的做法是直接把生成器传给线程池的starmap方法(而不是map),因为starmap会自动把生成器里的每个元组拆成多个参数传给目标函数。

修正后的完整代码

from multiprocessing.pool import ThreadPool
from functools import partial
import os
from os import path

__folder__ = os.getcwd()  # 根据你的实际路径调整

def iter_commit(LogFileName):
    with open(path.join(__folder__, LogFileName)) as LogFileName_file:
        for index, schema in enumerate(LogFileName_file):
            if len(schema) > 10:
                # 修正换行符的写法,原来的写法是错误的,应该用'\n'
                yield index, schema.rstrip('\n')

def makePool(cP, func, iters):
    try:
        pool = ThreadPool(cP)
        # 用starmap_async替代map_async,因为func需要接收两个参数
        pool.starmap_async(func, iters).get(99999)
        pool.close()
        pool.join()
    except Exception as e:
        print(f'Pool Error: {str(e)}')
        raise
    finally:
        pool.terminate()

def Parse(RoWnum, Link):
    print(RoWnum, Link)

# 调用时直接传入生成器即可,无需拆分下标
strSiteMap = "你的日志文件名.txt"  # 替换成实际文件名
makePool(50, Parse, iter_commit(strSiteMap))

关键修改点说明

  1. 替换map_async为starmap_async:
    • map会把迭代器的每个元素作为单个参数传给函数,而starmap会把每个元组元素拆成多个参数,正好匹配Parse(RoWnum, Link)的参数需求。
  2. 移除生成器的下标访问:
    直接把iter_commit(strSiteMap)整个生成器传给makePool,线程池会自动迭代生成器里的每一组(index, schema)。
  3. 修正换行符处理:
    原来的换行符写法无效,Python里换行符用\n表示,改成schema.rstrip('\n')才能正确去除行尾的换行。

额外补充:如果需要单独获取生成器的某个元素

如果只是想取生成器里的单个元素(比如第一个),可以用next()函数:

gen = iter_commit(strSiteMap)
first_index, first_schema = next(gen)  # 获取第一个元素

但这只适合获取少量元素,你的场景是批量处理所有元素,所以用starmap是最优解。

内容的提问来源于stack exchange,提问作者Dmitrij Holkin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:10:07