重组了JSON

时间:2013-11-08 03:50:31

标签: python json

需要在Python中将JSON重组为新结构。

例如:

{
  'a' : 1,
  'b' : 1,
  'd' : {'d1' : '1', 'd2' : 2},
  'm' : [
    {'x' : 6, 'y' : 5, 'z' : {'foo' : 'foo1', 'bar' : 'bar1'} },
    {'x' : 8, 'y' : 8, 'z' : {'foo' : 'foo2', 'bar' : 'bar2'} }
  ]
}

{
  'new_a' : 1,
  'new_d' : {'new_d1' : '1', 'new_d2' : 2},
  'new_m' : [
    {'new_x' : 6, 'new_z' : {'new_foo' : 'foo1', new_'bar : 'bar1'} },
    {'new_x' : 8, 'new_z' : {'new_foo' : 'foo2', 'new_bar : 'bar2'} }
  ]
}

有一种旧形式的旧JSON

的想法

有更优雅的方法吗?

import json

new_data = {}
new_data['new_a'] = old_data['a']
new_data['new_d'] = {}
new_data['new_d']['new_d1'] = old_data['d']['d1']
new_data['new_d']['new_d2'] = old_data['d']['d2']
new_data['new_m'] = {}
new_m = []
for m in old_data:
    new_m.append({'new_x' : m['x'], 'new_z' : {'new_foo' ....

2 个答案:

答案 0 :(得分:0)

您已经提到要求生成的代码必须删除“少数字段”。使用处理dicts和列表的递归循环,我们可以将所有键更改为new_并删除您指定的任何字段。

a = {
  'a' : 1,
  'b' : 1,
  'd' : {'d1' : '1', 'd2' : 2},
  'm' : [
    {'x' : 6, 'y' : 5, 'z' : {'foo' : 'foo1', 'bar' : 'bar1'} },
    {'x' : 8, 'y' : 8, 'z' : {'foo' : 'foo2', 'bar' : 'bar2'} }
  ]
}

def rename(dt):
    ndt = {}
    for k, v in dt.iteritems():
        if k == 'y':  # the keys that you wish to remove from the new dictionary
            continue
        if isinstance(v, dict):
            ndt['new_' + k] = rename(v)
        elif isinstance(v, list):
            ndt['new_' + k] = [rename(x) for x in v]
        else:
            ndt['new_' + k] = v
    return ndt

print rename(a)  # your expected dictionary

如果需要进行任何结构重组(例如,您想在其他地方移动值,或者如果您不想遵循您拥有的命名约定),那么您现有的代码已经是最干净的方法了如此。

答案 1 :(得分:0)

简单的递归解决方案将会:

def patch_keys(d, func):
    """
    For a given dictionary `d`, recursively applies `func` to its keys,
    filtering out those with `func(key)` evaluated to False. 
    For a list or tuple, applies `patch_keys` to each element.

    Intended usage:
    >>> patch_keys({1: 'a', 2: 'b'}, lambda x: x-1)
    {1: 'b'}
    """
    # we want to recursively apply self, i.e. `patch_keys(..., func=func)`
    # here functools.partial comes in handy
    self = partial(patch_keys, func=func)
    if isinstance(d, dict):
        # for a dict, apply self to values
        return {func(k): self(v) for k, v in d.items() if func(k)}
    elif isinstance(d, (list, tuple)):
        # for list and tuples, apply self to each element
        return type(d)(map(self, d))
    else:
        # else return as is
        return copy.deepcopy(d)

结果:

>>> old_data = {
...   'a' : 1,
...   'b' : 1,
...   'd' : {'d1' : '1', 'd2' : 2},
...   'm' : [
...     {'x' : 6, 'y' : 5, 'z' : {'foo' : 'foo1', 'bar' : 'bar1'} },
...     {'x' : 8, 'y' : 8, 'z' : {'foo' : 'foo2', 'bar' : 'bar2'} }
...   ]
... }
>>>

>>> patch_keys(old_data, new_keys)
{'new_d': {'new_d2': 2, 'new_d1': '1'}, 'new_m': [{'new_z': {'new_foo': 'foo1', 'new_bar': 'bar1'}}, {'new_z': {'new_foo': 'foo2', 'new_bar': 'bar2'}}], 'new_b': 1, 'new_a': 1}