2013-11-08 2 views
3

Нужно реорганизовать 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' .... 
+0

ли вы только хотите переименовать? –

+1

№ удалить несколько полей, небольшая структура реорганизации – couatl

ответ

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 

Если какая-либо структурная перестройка должна иметь место (например, вы хотите, чтобы переместить значение где-то еще, или если вы не хотите следовать соглашению об именах, у вас есть), то существующий код уже Самый чистый способ сделать это.

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}