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

嵌套字典内Pandas DataFrame新增列时set_item函数报错的排查与解决

嵌套字典与DataFrame的统一访问/设置问题解决

问题背景

我有一个名为dic的嵌套字典,节点层级深度不一,最终节点包含Pandas DataFrame。我需要一个统一方法来访问和设置任意节点的值(值可以是字典、DataFrame或DataFrame的列),于是编写了以下函数:

from functools import reduce
from operator import getitem, setitem

def get_item(path):
   return reduce(getitem, path, dic)

def set_item(path, value):
   reduce(lambda k,o,v=value: setitem(k,o,v), path, dic)
   return None

其中path由配置文件指定,格式示例为[key1, key2, table_name, [column1, column2]](对应3层深度结构)。

除了给DataFrame新增列的场景,其他操作均正常,但新增列时会触发如下错误:

TypeError: 'NoneType' object does not support item assignment

示例复现

初始化测试数据:

import pandas as pd

dic = {}
dic['key1'] = {}
dic['key1']['key2'] = {} 
dic['key1']['key2']['table1'] = pd.DataFrame({'column1': [1,2,3], 'column2': [10,20,30]})

获取操作正常执行:

get_item(['key1', 'key2', 'table1', ['column1']])

可正确返回对应列的数据。

但执行设置新列的操作时触发错误:

set_item(['key1', 'key2', 'table1', ['column3']], [100,200,300])

预期为给table1对应的DataFrame新增column3列,但实际抛出上述类型错误。

直接通过父节点赋值可以成功,但这种方式无法统一处理所有场景(比如设置字典节点、替换整个DataFrame等):

get_item(['key1', 'key2', 'table1'])['column3'] = [100,200,300]

报错原因

原set_item函数的核心问题在于:reduce会对路径中的每一个节点依次执行setitem操作,而setitem本身返回None。当路径最后一个元素是列名列表时,前一步执行setitem后得到的是None,后续迭代会尝试对None进行赋值,从而触发NoneType无法赋值的错误。

修复方案

拆分路径的最后部分,先通过path[:-1]获取到最终的父节点(比如示例中的DataFrame),再将最后一个节点(单个键或列名列表)单独应用到父节点上:

def set_item(path, value):
    if isinstance(path[-1], list):
        final_node = path[-1]
    else:
        final_node = [path[-1]]
    
    reduce(lambda k,o,v=value: setitem(k,o,v), final_node, get_item(path[:-1]))
    return None

修改后的函数可以统一处理所有场景:

  • 设置嵌套字典中的任意节点值
  • 替换整个DataFrame对象
  • 给DataFrame新增或修改单列/多列

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 09:33:22