为了账号安全,请及时绑定邮箱和手机立即绑定

在python中,如何最好地将key:value插入json,给定变量路径和值

在python中,如何最好地将key:value插入json,给定变量路径和值

绝地无双 2021-12-17 16:07:36
我需要创建一个 json 文件,给出路径及其值的字典。我编写了一些用于添加条目的代码,看起来它的功能和结果是正确的,但是作为 Python 新手,我想知道如何改进这一点,如果有一个功能相同的功能,模块中已经存在包含在 python 2.7 中?   def path_to_list(path):        if isinstance(path, (str,)):            map_list = path.split("/")            for i, key in enumerate(map_list):                if key.isdigit():                    map_list[i] = int(key)        else:            map_list = path        return map_listdef add_to_dictionary(dic, keys, value):    for i, key in enumerate(keys[:-1]):        if i < len(keys)-1 and isinstance(keys[i+1], int):            # Case where current key should be a list, since next key is            # is list position            if key not in dic.keys():                # Case list not yet exist                dic[keys[i]] = []                dic[keys[i]].append({})                dic = dic.setdefault(key, {})            elif not isinstance(dic[key], list):                # Case key exist , but not a list                # TO DO : check how to handle                print "Failed to insert " + str(keys) + ", trying to insert multiple to not multiple  "                break            else:                # Case where the list exist                dic = dic.setdefault(key, {})        elif i < len(keys)-1 and isinstance(key, int):            # Case where current key is instance number in a list            try:                # If this succeeds instance already exist                dic = dic[key]            except (IndexError,KeyError):                # Case where list exist , but need to add new instances  ,                # as key instance  not exist                while len(dic)-1 < key:                    dic.append({})                dic = dic[key]        else:            # Case where key is not list or instance of list            dic = dic.setdefault(key, {})    # Update value    dic[keys[-1]] = value一些键可能已经存在,然后我只更新值。数字键在它可以有多个值之前表示该键,我正在数组中的这个地方添加/更新值
查看完整描述

1 回答

?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

这是我使用嵌套字典实现的数据结构:


class Tree(dict):

    '''http://stackoverflow.com/questions/635483/what-is-the-best-way-to-implement-nested-dictionaries-in-python'''


    def __missing__(d, k):

        v = d[k] = type(d)()

        return v


    def grow(d, path, v):

        ps = map(lambda k: int(k) if k.isdigit() else k, path.split('/'))

        reduce(lambda d, k: d[k], ps[:-1], d)[ps[-1]] = v

测试这个:


t = Tree()

t.grow('a/0/b/c', 1)

print t

t['a'][2]['b']['c'] = 'string'

print t

t.grow('a/2/b/c', 'new_string')

print t

给出:


{'a': {0: {'b': {'c': 1}}}}

{'a': {0: {'b': {'c': 1}}, 2: {'b': {'c': 'string'}}}}

{'a': {0: {'b': {'c': 1}}, 2: {'b': {'c': 'new_string'}}}}

但是您希望整数索引字典是数组。下面的例程遍历嵌套的字典,将一些字典变成列表。它会进行一些复制,以免弄乱原始嵌套字典。我只会将它用作 outout 阶段的一部分。


import numbers

def keys_all_int(d):

    return reduce(lambda r, k: r and isinstance(k, numbers.Integral), d.keys(), True)


def listify(d):

    '''

    Take a tree of nested dictionaries, and

    return a copy of the tree with sparse lists in place of the dictionaries

    that had only integers as keys.

    '''

    if isinstance(d, dict):

        d = d.copy()

        for k in d:

            d[k] = listify(d[k])

        if keys_all_int(d):

            ds = [{}]*(max(d.keys())+1)

            for k in d:

                ds[k] = d[k]

            return ds

    return d

测试这个:


t = Tree()

t.grow('a/0/b/c', 1)

print listify(t)

t['a'][2]['b']['c'] = 'string'

print listify(t)

t.grow('a/2/b/c', 'new_string')

print listify(t)

给出:


{'a': [{'b': {'c': 1}}]}

{'a': [{'b': {'c': 1}}, {}, {'b': {'c': 'string'}}]}

{'a': [{'b': {'c': 1}}, {}, {'b': {'c': 'new_string'}}]}

最后,如果您正在处理 JSON,请使用该json模块:


import json

print json.dumps(listify(t),

    sort_keys=True, indent = 4, separators = (',', ': '))

给出:


{

    "a": [

        {

            "b": {

                "c": 1

            }

        },

        {},

        {

            "b": {

                "c": "new_string"

            }

        }

    ]

}


查看完整回答
反对 回复 2021-12-17
  • 1 回答
  • 0 关注
  • 361 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号