Python 3 使用 kwargs 替换嵌套字典值

标签 python python-3.x dictionary recursion

我已经查阅了文档并使用了许多队友的帮助,但无法弄清楚如何通过(在我的例子中)测试函数用 kwargs 提供的值替换字典:

模板字典:

{
    "id": "id_1234",
    "integer_value": 1234,
    "level_one": {
        "id": 1234,
        "foo": "true",
        "list_one": [],
        "list_two": [
            522
        ],
        "url": "http://google.com",
        "level_two": {
            "thing_one": {
                "yes": "false",
                "no": "false"
            },
            "thing_two": {
                "yes": "false",
                "no": "false"
            }
        },
        "another_field": "true",
        "bar": 15000
    }
}

递归字典函数:

def update_dictionary(template_dict, **kwargs):
for k, v in kwargs.items():
    print(v)
    print(isinstance(v, collections.Mapping))
    if isinstance(v, collections.Mapping):
        print("This is the k value")
        print(k)
        template_dict[k] = update_dictionary(template_dict.get(k, {}), v)
    else:
        print("We're going into the else now")
        template_dict[k] = v
return template_dict

我从这里的另一个论坛获得了上述功能,但在传递 kwargs 时它似乎不起作用。对于不在嵌套字典第一层中的任何字段,isinstance 检查结果为 False。如有任何帮助,我们将不胜感激!

测试中传递 kwargs 的行:

new_dict = update_dictionary(template_dict, another_field = 'false', integer_value=12345)

最佳答案

因此,您需要继续传递kwargs,否则第一级之后的所有内容都将没有任何内容可以替换!这是一个简单的演示:

def update_dict(d, **kwargs):
    new = {}
    for k, v in d.items():
        if isinstance(v, dict):
            new[k] = update_dict(v, **kwargs)
        else:
            new[k] = kwargs.get(k, v)
    return new

实际操作:

In [16]: template
Out[16]:
{'id': 'id_1234',
 'integer_value': 1234,
 'level_one': {'another_field': 'true',
  'bar': 15000,
  'foo': 'true',
  'id': 1234,
  'level_two': {'thing_one': {'no': 'false', 'yes': 'false'},
   'thing_two': {'no': 'false', 'yes': 'false'}},
  'list_one': [],
  'list_two': [522],
  'url': 'http://google.com'}}

In [17]: update_dict(template, another_field = 'false', integer_value=12345)
Out[17]:
{'id': 'id_1234',
 'integer_value': 12345,
 'level_one': {'another_field': 'false',
  'bar': 15000,
  'foo': 'true',
  'id': 1234,
  'level_two': {'thing_one': {'no': 'false', 'yes': 'false'},
   'thing_two': {'no': 'false', 'yes': 'false'}},
  'list_one': [],
  'list_two': [522],
  'url': 'http://google.com'}}

再说一遍:

In [19]: update_dict(template, another_field = 'false', integer_value=12345, no='FOO')
Out[19]:
{'id': 'id_1234',
 'integer_value': 12345,
 'level_one': {'another_field': 'false',
  'bar': 15000,
  'foo': 'true',
  'id': 1234,
  'level_two': {'thing_one': {'no': 'FOO', 'yes': 'false'},
   'thing_two': {'no': 'FOO', 'yes': 'false'}},
  'list_one': [],
  'list_two': [522],
  'url': 'http://google.com'}}

请注意,此实现返回一个全新的dict,这就是我假设您想要的,因为template是一个模板,并且您写道:

new_dict = update_dictionary(template_dict, another_field = 'false', integer_value=12345)

但是如果您实际上想要就地修改,您只需更改为:

def update_dict(d, **kwargs):
    for k, v in d.items():
        if isinstance(v, dict):
            update_dict(v, **kwargs)
        else:
            d[k] = kwargs.get(k, v)

我会选择非就地版本...注意,你可以用厚颜无耻的俏皮话来做到这一点,但我不推荐它:

def update_dict(d, **kwargs):
    return {k:update_dict(v, **kwargs) if isinstance(v, dict) else kwargs.get(k,v) for k,v in d.items()}

关于Python 3 使用 kwargs 替换嵌套字典值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47146838/

相关文章:

python - 根据来自另一个列表的 True/False 过滤列表中的元素

python - 如何键入提示实例级函数(即不是方法)?

c# - 创建由数据库驱动的对象来填充 TreeView - 非常慢

python - 从字典创建 Python DataFrame,其中键是列名,值构成行

Python 正则表达式 : Get regex pattern in a text file and store in an array or list

python - 为什么在表达式字段中不允许生成器中未加括号的元组?

Python 字典和列表混淆

python - 如何在支持多种数据格式的 Pandas 中合并日期?

python - 如何更新嵌套字典中键的值?

c++ - 为什么 STL map 不起作用?