python的字典中,如何向指定路径添加值?

想实现一个函数,传入字典,路径/键的列表,返回修改后的字典。
大概是这个意思

def add_value(dict, path, value):
    # dict是待修改的字典
    # path是路径,列表形式,如`['A', 'B', 'C']`, A目录下有B目录,B目录下有C目录
    # value是一个元组、列表、字典或者字符串
    ……
    return dict

需要实现的功能大概像这样:

d = {}
add_value(d, ['A', 'B', 'C'], ('output.txt', '2mb'))
{'A': {'B': {'C': [('output.txt', '2mb')]}}}
add_value(d, ['X', 'Y'], ('log.txt', '10kb'))
{'A': {'B': {'C': 'string'}}, 'X': {'Y': [('log.txt', '10kb'),]}}
add_value(d, ['A', 'B', 'C'], ('video.mp4', '2GB'))
{'A': {'B': {'C': [('output.txt', '2mb'), ('video.mp4', '2GB')]}}, 'X': {'Y': {'Z': [('log.txt', '10kb'),]}}}

path的长度是不定的,或者说目录的深度是不定的,所以好像要用循环调用,不能用几个if结构。
python新手,实在不知如何实现,求教。

阅读 4.8k
2 个回答

如果不是做特定的oj题目的话, 推荐使用xml, 更直观, 也更好管理

from lxml import etree


def gen_xpath(path):
    return '//root/' + '/'.join(path)


def add_value(root, path, value):
    purpose_path = gen_xpath(path)
    folder = root.xpath(purpose_path)
    parent_folder = root
    if not folder:
        for i, name in enumerate(path, 1):
            temp_path = gen_xpath(path[:i])
            temp_folder = root.xpath(temp_path)
            if not temp_folder:
                parent_folder = etree.SubElement(parent_folder, name)
            else:
                parent_folder = temp_folder
    
    folder = root.xpath(purpose_path)[0]
    file = etree.SubElement(folder, 'file')
    file.set('name', value[0])
    file.set('size', value[1])


if __name__ == '__main__':
    root = etree.Element('root')
    add_value(root, ['A', 'B', 'C'], ('output.txt', '2mb'))
    add_value(root, ['X', 'Y'], ('log.txt', '10kb'))
    add_value(root, ['A', 'B', 'C'], ('video.mp4', '2GB'))
    etree.ElementTree(root).write('test.xml', pretty_print=True)

输出结果:

<root>
  <A>
    <B>
      <C>
        <file name="output.txt" size="2mb"/>
        <file name="video.mp4" size="2GB"/>
      </C>
    </B>
  </A>
  <X>
    <Y>
      <file name="log.txt" size="10kb"/>
    </Y>
  </X>
</root>
def add_value(dict_obj, path, value):
  obj = dict_obj
  for i ,v in enumerate(path):
    if i + 1 == len(path):
      if not isinstance(obj.get(v, ''), list):
        obj[v] = list()
      obj[v].append(value)
      continue
    obj[v] = obj.get(v, '') or dict()
    obj = obj[v]
  return dict_obj

d = {}
print add_value(d, ['A', 'B', 'C'], ('output.txt', '2mb'))
print add_value(d, ['X', 'Y'], ('log.txt', '10kb'))
print add_value(d, ['A', 'B', 'C'], ('video.mp4', '2GB'))
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题