代码之家  ›  专栏  ›  技术社区  ›  prayner

更新嵌套字典包含列表中的项

  •  -1
  • prayner  · 技术社区  · 4 月前

    我正在编写一个可以更新嵌套字典中任何项目的方法。该方法接受路径、json和值:

    from functools import reduce
    import operator
    
    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'}]}
    
    def update_attribute(element, json, new_value):
        *path, last = element.split('.')
        target = reduce(operator.getitem, path, json)
        target[last] = new_value
        return json
    
    update_attribute('fields.player', json_test, 'Mbappe')
    

    但是,这种方法不起作用,因为字典中有一个列表。

    ---------------------------------------------------------------------------
    TypeError                                 Traceback (most recent call last)
    Cell In[114], line 1
    ----> 1 update_attribute("fields.player", json_name_ab_asr, "test")
    
    Cell In[111], line 3, in update_attribute(element, json, new_value)
          1 def update_attribute(element, json, new_value):
          2     *path, last = element.split('.')
    ----> 3     target = reduce(operator.getitem, path, json)
          4     target[last] = new_value
          5     return json
    
    TypeError: list indices must be integers or slices, not str
    

    有什么变通办法吗?

    1 回复  |  直到 4 月前
        1
  •  1
  •   Barmar    4 月前

    转换的数字分量 path 到整数。然后在调用函数时将下标添加到元素字符串中

    from functools import reduce
    import operator
    
    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'}]}
    
    def update_attribute(element, json, new_value):
        *path, last = element.split('.')
        path = [int(item) if item.isdigit() else item for item in path]
        target = reduce(operator.getitem, path, json)
        target[last] = new_value
        return json
    
    update_attribute('fields.0.player', json_test, 'Mbappe')
    

    这并不完美,因为如果你有一个键是数字字符串的字典,它就不起作用了。