python - 在python中,如何最好地插入给定变量路径和值的键:value to json,

标签 python json list dictionary

我需要创建一个 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_list


def 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

my_dict1 ={}
add_to_dictionary(my_dict1, path_to_list("a/0/b/c"), 1)
print my_dict1

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

add_to_dictionary(my_dict1, path_to_list("a/2/b/c"), "string")
print my_dict1

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

add_to_dictionary(my_dict1, path_to_list("a/2/b/c"), "new string")
print my_dict1

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

某些键可能已经存在,然后我只更新值。

数字键表示该键之前可以有多个值,我正在数组中的这个位置添加/更新值

最佳答案

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

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'}}}}

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

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"
            }
        }
    ]
}

关于python - 在python中,如何最好地插入给定变量路径和值的键:value to json,,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55371617/

相关文章:

python - 如何使用其他数据框中的列值选择数据框中的列值

python - 如何从 Django 项目(及其所有表)中删除应用程序

python - 如何在 Bluemix 中安装/导入依赖项并执行 Python 文件

arrays - 获取 JSON 数组内的 UICollectionView 单元格 ID 并将其设为全局

java - Thymeleaf - 在 JAVA 中传递模型

python - 为什么 Keras fit_generator() 在实际 "training"之前加载

php - WordPress + 插件非常简单 SSL + json 返回错误

php mysql从json中的多个表中获取数据

Java:如何将 List<T> 中的对象添加到 Map(键:Enum,值 List<T>)

list - Haskell ~ last 是否遍历整个列表?