Skip to main content
 首页 » 编程设计

python之python中Json的点符号

2025年05月04日15xiaohuochai

我从 Loggly 服务以点表示法接收数据,但要将数据放回原处,它必须采用 JSON 格式。

因此,我需要转换:

{'json.message.status.time':50, 'json.message.code.response':80, 'json.time':100} 

进入:

{'message': {'code': {'response': 80}, 'status': {'time': 50}}, 'time': 100} 

我已经将一个函数组合在一起,但我想知道是否有更直接、更简单的方法来实现相同的结果。

def dot_to_json(a): 
 
    # Create root for JSON tree structure 
    resp = {} 
 
    for k,v in a.items(): 
        # eliminate json. (if metric comes from another type, it will keep its root) 
        k = re.sub(r'\bjson.\b','',k) 
        if '.' in k: 
            # Field has a dot 
            r = resp 
            s = '' 
            k2 =  k.split('.') 
            l = len(k2) 
            count = 0 
            t = {} 
            for f in k2: 
                count += 1 
                if f not in resp.keys(): 
                    r[f]={} 
                r = r[f] 
                if count < l: 
                    s += "['" + f + "']" 
                else: 
                    s = "resp%s" % s 
                    t = eval(s) 
                    # Assign value to the last branch 
                    t[f] = v 
        else: 
            r2 = resp 
            if k not in resp.keys(): 
                r2[k] = {} 
            r2[k] = v 
    return resp 

请您参考如下方法:

您可以将路径转换为字典访问:

def dot_to_json(a): 
    output = {} 
    for key, value in a.iteritems(): 
        path = key.split('.') 
        if path[0] == 'json': 
            path = path[1:] 
        target = reduce(lambda d, k: d.setdefault(k, {}), path[:-1], output) 
        target[path[-1]] = value 
    return output 

这将 key 作为路径,忽略第一个 json 部分。用reduce()您可以遍历 path 的元素(最后一个除外)并使用它获取嵌套字典。

本质上,您从 output 开始,为 path 中的每个元素获取值,并将该值用作下一次迭代的输入。这里dict.setdefault()每次键尚不存在时,默认使用一个新的空字典。对于路径 ['foo', 'bar', 'baz'] 这归结为调用 output.setdefault('foo', {}).setdefault('bar', {}).setdefault('baz', {}),只是更紧凑并支持任意长度的路径。

然后使用最里面的字典设置以路径的最后一个元素为键的值。

演示:

>>> def dot_to_json(a): 
...     output = {} 
...     for key, value in a.iteritems(): 
...         path = key.split('.')[1:]  # ignore the json. prefix 
...         target = reduce(lambda d, k: d.setdefault(k, {}), path[:-1], output) 
...         target[path[-1]] = value 
...     return output 
...  
>>> dot_to_json({'json.message.status.time':50, 'json.message.code.response':80, 'json.time':100})) 
{'message': {'status': {'time': 50}, 'code': {'response': 80}}, 'time': 100}