
本文介绍一种健壮的 Python 方法,用于更新含列表的嵌套字典中任意路径的字段值;核心是自动识别并转换路径中的数字索引(如 "fields.0.player"),避免 TypeError: list indices must be integers 错误。
本文介绍一种健壮的 python 方法,用于更新含列表的嵌套字典中任意路径的字段值;核心是自动识别并转换路径中的数字索引(如 `"fields.0.player"`),避免 `typeerror: list indices must be integers` 错误。
在处理 JSON 或嵌套配置结构时,常需动态修改深层字段(例如 fields.0.player)。但原生 operator.getitem 无法直接处理混合类型路径——当路径包含列表索引(如 "0")时,若未转为整数,会因字符串索引引发 TypeError。
以下是一个改进版 update_attribute 函数,支持字典键与列表整数索引的无缝混合访问:
from functools import reduce
import operator
def update_attribute(path: str, data: dict, new_value) -> dict:
"""
更新嵌套字典/列表结构中指定路径的值。
支持路径格式如:'fields.0.player', 'location.geometry.coordinates.1'
自动将路径中纯数字字符串(如 '0', '12')转为 int,其余保留为 str。
Args:
path: 以 '.' 分隔的路径字符串
data: 待更新的嵌套数据结构(dict/list)
new_value: 要设置的新值
Returns:
更新后的原数据对象(就地修改,返回引用)
"""
*keys, last_key = path.split('.')
# 将路径中可转为整数的项转为 int(适配 list 索引),其余保持为 str(适配 dict key)
keys = [int(k) if k.isdigit() else k for k in keys]
# 定位到目标容器(父级对象)
target_container = reduce(operator.getitem, keys, data)
# 更新目标字段
target_container[last_key] = new_value
return data
# 示例数据
json_test = {
'request_version': 'v1.0',
'fields': [{
'team': [{'name': 'Real Madrid', 'colour': 'white'}],
'location': {
'type': 'Feature',
'geometry': {'type': 'Point', 'coordinates': [0, 53]}
},
'query': {'filter': '2024/25'},
'player': 'Bellingham'
}]
}
# ✅ 正确更新列表内字典的字段
update_attribute('fields.0.player', json_test, 'Mbappe')
print(json_test['fields'][0]['player']) # 输出: 'Mbappe'
# ✅ 更新嵌套列表元素(如 coordinates[1])
update_attribute('fields.0.location.geometry.coordinates.1', json_test, 54)
print(json_test['fields'][0]['location']['geometry']['coordinates']) # [0, 54]⚠️ 注意事项与局限性:
- 该方案假设数字型路径段仅用于列表索引,不支持字典中以数字字符串为 key 的场景(如
{'123': 'value'}中的'123'会被误转为123导致KeyError)。若需兼容此类情况,应改用更明确的语法(如fields.[0].player)或增加类型提示机制。 - 函数执行就地修改,不创建新副本;如需不可变更新,可结合
copy.deepcopy()预处理。 - 路径必须存在且每级均可访问(
reduce过程中若某级不存在会抛KeyError或IndexError),生产环境建议增加路径校验或使用try/except包裹。
✅ 总结:通过智能解析路径并动态转换索引类型,该方法在简洁性与实用性间取得良好平衡,适用于大多数 API 请求体、配置模板或数据清洗场景中的动态赋值需求。

















