3

需要在 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' ....
4

2 回答 2

0

您提到了结果代码必须删除“少数字段”的要求。使用处理字典和列表的递归循环,我们可以将所有键更改为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

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

于 2013-11-08T06:04:03.210 回答
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}
于 2013-11-08T06:05:46.237 回答