首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在任意深度的嵌套dict中更新值,而不更改Python中dict的其余部分

在任意深度的嵌套dict中更新值,而不更改Python中dict的其余部分
EN

Stack Overflow用户
提问于 2022-11-22 12:58:46
回答 1查看 16关注 0票数 0

因此,我在Python中有一个嵌套字典:

代码语言:javascript
复制
{'entry': {'definition': 'str',
       'endTime': 'str',
       'entryID': {'identifierType': 'str', 'identifierValue': 'str'},
       'instrument': {'FIB': {'FIBSpotSize': {'notes': 'str',
                                              'qualifier': 'str',
                                              'uncertainty': {'uncertaintyType': 'str',
                                                              'value': 'float'},
                                              'unit': 'str',
                                              'value': 'float'},
                              'angleToEBeam': {'notes': 'str',
                                               'qualifier': 'str',
                                               'uncertainty': {'uncertaintyType': 'str',
                                                               'value': 'float'},
                                               'unit': 'str',
                                               'value': 'float'},...
.
.
.

我想要一种方法,简单地访问一个特定的键值对,给定一个任意长的密钥。

例如,我想要entry.instrument.angleToEBeam.uncertainty.value,因为我想更新value的值。我想要编写一个函数,它接受任意长度键的列表,其中最后一个键是我想要更新的值,以及我想设置/更新的值。对于如何导航/遍历这些嵌套字典,我有点困惑。

作为我想要做的事情的一个例子,我需要更新一些值,如下所示

代码语言:javascript
复制
{'entry.instrument.angleToEBeam.uncertainty.value': 2.23', ...}

我想将这个列表添加到一些函数中,这样它就可以更新嵌套的dict,使其具有值而不是预期的类型,这里只显示了uncertainty参数:

代码语言:javascript
复制
{'entry': {'definition': 'str',
       'endTime': 'str',
       'entryID': {'identifierType': 'str', 'identifierValue': 'str'},
       'instrument': {'FIB': {'FIBSpotSize': {'notes': 'str',
                                              'qualifier': 'str',
                                              'uncertainty': {'uncertaintyType': 'str',
                                                              'value': 'float'},
                                              'unit': 'str',
                                              'value': 'float'},
                              'angleToEBeam': {'notes': 'str',
                                               'qualifier': 'str',
                                               'uncertainty': {'uncertaintyType': 'pct',
                                                               'value': 3.102},
                                               'unit': 'deg',
                                               'value': 2.23},...
.
.
.

最终,这些文件必须作为JSON文件导出,因此产生了嵌套字典。有什么想法吗?一些相关的线程:

但我想不出如何将它们应用到我的情况中,因为它们完全是在处理整件事。

EN

回答 1

Stack Overflow用户

发布于 2022-11-22 14:52:15

JMESPath是查询嵌套dict的强大解决方案,但不幸的是,它似乎没有提供lvalue选项(修改)。

最后,下面是一些根据基本原则构建的东西:

代码语言:javascript
复制
def xupdate(dct, path, value, createkeys=False):
    if path:
        k, *path = path
        subdct = dct.get(k, {}) if createkeys else dct[k]
        return {**dct, **{k: xupdate(subdct, path, value)}}
    return value

def dotupdate(dct, dotmods, createkeys=False):
    for kdot, value in dotmods.items():
        dct = xupdate(dct, kdot.split('.'), value, createkeys)
    return dct

示例

代码语言:javascript
复制
dct = {
    'entry': {
        'definition': 'str', 'endTime': 'str', 'entryID': {
            'identifierType': 'str', 'identifierValue': 'str'},
        'instrument': {
            'FIB': {
                'FIBSpotSize': {
                    'notes': 'str', 'qualifier': 'str', 'uncertainty': {
                        'uncertaintyType': 'str', 'value': 'float'},
                    'unit': 'str', 'value': 'float'},
                'angleToEBeam': {
                    'notes': 'str', 'qualifier': 'str', 'uncertainty': {
                        'uncertaintyType': 'str', 'value': 'float'},
                    'unit': 'str', 'value': 'float'}}}}}

dotmods = {
    'entry.instrument.FIB.angleToEBeam.uncertainty.value': 2.23,
    'entry.endTime': '2023-01-01',
}

>>> dotupdate(dct, dotmods)
{'entry': {'definition': 'str',
  'endTime': '2023-01-01',
  'entryID': {'identifierType': 'str', 'identifierValue': 'str'},
  'instrument': {'FIB': {'FIBSpotSize': {'notes': 'str',
     'qualifier': 'str',
     'uncertainty': {'uncertaintyType': 'str', 'value': 'float'},
     'unit': 'str',
     'value': 'float'},
    'angleToEBeam': {'notes': 'str',
     'qualifier': 'str',
     'uncertainty': {'uncertaintyType': 'str', 'value': 2.23},
     'unit': 'str',
     'value': 'float'}}}}}

备注

  1. createkeys:如果是True,则创建原始dict中不存在的键(例如排字、不完整路径)。在最初的问题中,有一个对不存在的'entry.instrument.angleToEBeam.uncertainty.value' (缺失.FIB)的引用;这将创建缺少的键,这可能是不想要的。
  2. 嵌套dict的顺序保持不变。
  3. 原始的dict本身没有被修改;返回的值是半拷贝(对于被修改的部分是深拷贝;未经修改的子块是通过引用复制的)。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74533006

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档