【问题标题】:Python: Replace values in nested dictionaryPython:替换嵌套字典中的值
【发布时间】:2019-09-06 08:27:55
【问题描述】:

只要键是'current_values',我想用与整数相同的值替换值(格式化为字符串)。

d = {'id': '10', 'datastreams': [{'current_value': '5'}, {'current_value': '4'}]}

期望的输出:

d = {'id': '10', 'datastreams': [{'current_value': 5}, {'current_value': 4}]}

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 您在 dict 中混合列表的事实可能会使其变得棘手。
  • @DirtyBit 他可能是 SO 的新手,所以用负面反应吓跑他并不是很有吸引力。
  • @JohnnyMcFly 通常最好通过提供您尝试解决问题的示例来应用MCVE guide 中定义的原则。牢记未来。
  • sry 伙计们,你说得对,我以后会考虑的,谢谢!

标签: python dictionary iteration


【解决方案1】:

以下代码替换字典中的值(子字符串)。它适用于嵌套的 json 结构并处理 json、列表和字符串类型。如果需要,您可以添加其他类型。

def dict_replace_value(d, old, new):
    x = {}
    for k, v in d.items():
        if isinstance(v, dict):
            v = dict_replace_value(v, old, new)
        elif isinstance(v, list):
            v = list_replace_value(v, old, new)
        elif isinstance(v, str):
            v = v.replace(old, new)
        x[k] = v
    return x


def list_replace_value(l, old, new):
    x = []
    for e in l:
        if isinstance(e, list):
            e = list_replace_value(e, old, new)
        elif isinstance(e, dict):
            e = dict_replace_value(e, old, new)
        elif isinstance(e, str):
            e = e.replace(old, new)
        x.append(e)
    return x

# See input and output below
b = dict_replace_value(a, 'string', 'something')

输入:

a = {
    'key1': 'a string',
    'key2': 'another string',
    'key3': [
        'a string',
        'another string',
        [1, 2, 3],
        {
            'key1': 'a string',
            'key2': 'another string'
        }
    ],
    'key4': {
        'key1': 'a string',
        'key2': 'another string',
        'key3': [
            'a string',
            'another string',
            500,
            1000
        ]
    },
    'key5': {
        'key1': [
            {
                'key1': 'a string'
            }
        ]
    }
}

输出:

{
   "key1":"a something",
   "key2":"another something",
   "key3":[
      "a something",
      "another something",
      [
         1,
         2,
         3
      ],
      {
         "key1":"a something",
         "key2":"another something"
      }
   ],
   "key4":{
      "key1":"a something",
      "key2":"another something",
      "key3":[
         "a something",
         "another something",
         500,
         1000
      ]
   },
   "key5":{
      "key1":[
         {
            "key1":"a something"
         }
      ]
   }
}

【讨论】:

  • 哪个是最通用和可重复使用的答案,应该标记为正确的答案!!!
  • 我遇到了同样的问题,大多数答案并没有比一级嵌套结构更进一步。所以这就是我想出上述答案的原因。
  • @Nebulastic 很好的答案。没有人会更深入。
【解决方案2】:
d = {'id': '10', 'datastreams': [{'current_value': '5'}, {'current_value': '4'}]}

for elem in d['datastreams']:      # for each elem in the list datastreams
    for k,v in elem.items():       # for key,val in the elem of the list 
        if 'current_value' in k:   # if current_value is in the key
            elem[k] = int(v)       # Cast it to int
print(d)

输出

{'id': '10', 'datastreams': [{'current_value': 5}, {'current_value': 4}]}

【讨论】:

    【解决方案3】:

    一般方法(假设您事先不知道 dict 的哪个键指向列表)是迭代 dict 并检查其值的类型,然后在需要时再次迭代到每个值。

    在您的情况下,您的字典可能包含一个字典列表作为值,因此检查一个值是否为列表类型就足够了,如果是,则遍历列表并更改您需要的字典。

    可以使用如下函数递归完成:

    def f(d):
        for k,v in d.items():
            if k == 'current_value':
                d[k] = int(v)
            elif type(v) is list:
                for item in v:
                    if type(item) is dict:
                        f(item)
    
    >>> d = {'id': '10', 'datastreams': [{'current_value': '5'}, {'current_value': '4'}]}
    >>> f(d)
    >>> d
    {'id': '10', 'datastreams': [{'current_value': 5}, {'current_value': 4}]}  
    

    【讨论】:

    • 这是最简单的答案。
    【解决方案4】:

    可以通过列表理解来完成:

    d['datastreams'] = [{'current_value': int(ds['current_value'])} if ('current_value' in ds) else ds for ds in d['datastreams']]
    

    【讨论】:

      【解决方案5】:

      您可以使用 ast.literal_eval 在 d['datastreams'] 列表中使用 current_value 键评估 items 的基础值。然后检查类型是否为int,使用isinstance 获取此类值。最后,将这些值类型转换为int

      import ast
      d = {'id': '10', 'datastreams': [{'current_value': '5'}, {'current_value': '4'}]}
      for i in d['datastreams']:
          for k,v in i.items():
              if 'current_value' in k and isinstance(ast.literal_eval(v),int):
                  i[k] = int(v)
      #Output:
      print(d)
      {'id': '10', 'datastreams': [{'current_value': 5}, {'current_value': 4}]}
      

      【讨论】:

        【解决方案6】:

        你可以用这个方法 这将循环检查 list 中的 current_value 并通过将值传递给 int() 函数将其更改为整数:

        for value in d.values():
            for element in value:
                if 'current_value' in element:
                    element['current_value'] = int(element['current_value'])
        

        【讨论】:

          猜你喜欢
          • 2023-01-23
          • 2022-10-13
          • 2016-11-24
          • 2019-01-25
          • 2018-04-19
          • 1970-01-01
          • 1970-01-01
          • 2012-07-26
          • 1970-01-01
          相关资源
          最近更新 更多