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

如何在遍历字典/列表时为Pandas DataFrame添加对应request_id列?

解决DataFrame添加request_id列全部为最后一个值的问题

这个问题我之前也碰到过!本质上是循环中变量引用或者DataFrame对象复用导致的,要么是你在循环里没有为每个请求创建独立的DataFrame,要么是变量的延迟绑定让所有df都指向了最后一次循环的request_id值。

先看正确的实现代码

假设我们有一个模拟的API调用函数call_api,核心是在每次循环中:

  1. 取出当前请求的request_id和参数
  2. 调用API获取结果
  3. 把结果转为全新的DataFrame
  4. 为这个新df添加request_id列(用当前循环的request_id值)
  5. 将df追加到responses列表
import pandas as pd

# 模拟API调用函数,实际替换成你的真实API调用
def call_api(name):
    # 假设API返回这样的结构
    return [{'product': f"{name}_item1"}, {'product': f"{name}_item2"}]

dict_example = { 
    'Request_1': { 'request_id' : '1', 'name' : 'Foo' }, 
    'Request_2': { 'request_id' : '2', 'name' : 'Bar' }, 
    'Request_3': { 'request_id' : '3', 'name' : 'Barbie' } 
}

responses = []

# 正确的遍历方式
for req_info in dict_example.values():
    current_request_id = req_info['request_id']
    current_name = req_info['name']
    
    # 调用API获取数据
    api_response = call_api(current_name)
    
    # 将API结果转为新的DataFrame
    df = pd.DataFrame(api_response)
    
    # 为当前df添加request_id列,用当前循环的request_id值
    df['request_id'] = current_request_id
    
    # 将新的df加入列表
    responses.append(df)

# 验证结果
for idx, df in enumerate(responses):
    print(f"第{idx+1}个DataFrame的request_id列:")
    print(df['request_id'].unique())

为什么你的代码会出现所有request_id都是3?

最常见的两种原因:

  1. 复用同一个DataFrame对象:如果在循环外先定义了一个df,然后每次循环只是修改这个df的内容再append到列表,由于列表存储的是对象引用,最后所有列表项都会指向最后一次修改后的df,自然所有request_id都是最后一个值。
    典型错误示例(如果是修改现有df而非创建新df):
    responses = []
    df = pd.DataFrame(columns=['product', 'request_id'])  # 循环外定义的固定df
    for req_info in dict_example.values():
        current_request_id = req_info['request_id']
        api_response = call_api(req_info['name'])
        df = pd.DataFrame(api_response)
        df['request_id'] = current_request_id
        responses.append(df)  # 若此处是修改原有df而非重新赋值,就会导致引用问题
    
  2. 异步场景下的闭包延迟绑定:如果你的API调用是异步的(比如用asyncio),在创建任务时使用闭包引用request_id,Python的闭包是延迟绑定的,所有任务会在循环结束后才去取request_id的值,也就是最后一个值3。
    错误示例:
    import asyncio
    async def async_call_api(name):
        await asyncio.sleep(0.1)
        return [{'product': f"{name}_item1"}]
    
    responses = []
    async def main():
        tasks = []
        for req_info in dict_example.values():
            request_id = req_info['request_id']
            # 错误:闭包延迟绑定,所有任务都会用最后一个request_id
            task = asyncio.create_task(
                pd.DataFrame(await async_call_api(req_info['name'])).assign(request_id=request_id)
            )
            tasks.append(task)
        responses.extend(await asyncio.gather(*tasks))
    
    解决异步场景的问题,可以用默认参数绑定当前值:
    task = asyncio.create_task(
        (lambda rid=request_id: pd.DataFrame(await async_call_api(req_info['name'])).assign(request_id=rid))()
    )
    

额外优化建议

  • 如果API返回的数据结构一致,可以最后把所有df合并成一个大的DataFrame,方便后续处理:
    combined_df = pd.concat(responses, ignore_index=True)
    
  • 可以用列表推导式简化代码(确保每次创建新df):
    responses = [
        pd.DataFrame(call_api(req['name'])).assign(request_id=req['request_id'])
        for req in dict_example.values()
    ]
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:43:47