2014-01-21 4 views
0

У меня есть язык конкретные словари следуют точно такую ​​же структуру данных, единственное, что делает их отличается язык, смотрите пример ниже,Объединение значений словаря inPython

Так, в принципе у меня есть словарь, как следовать ВХОД

{ 
     'english': [ 
      { 
       'id': "field_1", 
       'label': "Items", 
       'type': "choicefield", 
       'choices': [ 
        ["", "All Items"], 
        [0, "Item 0"], 
        [1, "Item 1"], 
        [2, "Item 2"] 
       ] 
      }, 
      { 
       'id': "field_2", 
       'label': "Keywords", 
       'type': "textfield", 
       'choices': None 
      }, 
      { 
       "id": "field_3", 
       "label": "Agree?", 
       "type": "checkbox", 
       "choices": None 
      }, 
     ], 
     'french': [ 
      { 
       'id': "field_1", 
       'label': "Items (fr translated)", 
       'type': "choicefield", 
       'choices': [ 
        ["", "All Items (fr translated)"], 
        [0, "Item 0 (fr translated)"], 
        [1, "Item 1 (fr translated)"], 
        [2, "Item 2 (fr translated)"] 
       ] 
      }, 
      { 
       'id': "field_2", 
       'label': "Keywords (fr translated)", 
       'type': "textfield", 
       'choices': None 
      } 
     ] 
} 

И то, что я хочу в качестве выходного сигнала является ответом API в следующем составе (которая в основном объединенный язык/переводные поля),

ЗАПЛАНИРОВАННЫЕ

[ 
    { 
     'id': "field_1", 
     'label': { 
      'english': "Items", 
      'french': "Items (fr translated)", 
     }, 
     'type': 'choicefield', 
     'choices': [ 
      ["", {"english": "All Items", "french": "All Items (fr translated)"}], 
      [0, {"english": "Item 0", "french": "Item 0 (fr translated)"}], 
      [1, {"english": "Item 1", "french": "Item 1 (fr translated)"}], 
      [2, {"english": "Item 2", "french": "Item 2 (fr translated)"}], 
     ] 
    }, 
    { 
     'id': "field_2", 
     'label': { 
      'english': "Keywords", 
      'french': "Keywords (fr translated)", 
     }, 
     'type': 'textfield', 
     'choices': [] 
    } 
] 

что уже сделано до сих пор

def merge_options(options_dict): 
    from copy import deepcopy 
    MERGE_FIELD_LIST = ['label'] 
    languages = options_dict.keys() 
    data_copy = deepcopy(options_dict[languages[0]]) 
    for i, item in enumerate(data_copy): 
     for field in MERGE_FIELD_LIST: 
      field_dict = {} 
      for lang in languages: 
       try: 
        field_dict.update({lang: options_dict[lang][i][field]}) 
       except KeyError: 
        pass 
      item.update({field: field_dict}) 
    return data_copy 

Который на самом деле дает быть желательным или поле «метка», но я не в состоянии объединить поле опций, а также код, написанный очень уродливый, а не питонический способ делать, глядя на любой более быстрый и быстрый подход к этому.

Благодаря

+6

(1) Что вы пробовали до сих пор? (2) Каков ваш вопрос? –

+2

Привет, извините за то, что не предоставил достаточную информацию, просто обновленный вопрос с более подробной информацией. Спасибо – Adeel

ответ

2

Grab английская версия первого, а затем сливают в других языках:

# build initial structure with English labels 
fields = [f.copy() for f in per_language['english']] 
for field in fields: 
    field['label'] = {'english': field['label']} 
    if field['choices'] is not None: 
     field['choices'] = [[id, {'english': label}] for id, label in field['choices']] 

# copy in the translated labels 
for language, language_fields in per_language.iteritems(): 
    if language == 'english': continue 
    # assumption: fields are always listed in the same order 
    for field, language_field in zip(fields, language_fields): 
     field['label'][language] = language_field['label'] 
     if field['choices'] is not None: 
      for (id, choice_labels), (_, language_label) in zip(field['choices'], language_field['choices']): 
       choice_labels[language] = language_label 

Это производит:

[{'choices': [['', 
       {'english': 'All Items', 
       'french': 'All Items (fr translated)'}], 
       [0, {'english': 'Item 0', 'french': 'Item 0 (fr translated)'}], 
       [1, {'english': 'Item 1', 'french': 'Item 1 (fr translated)'}], 
       [2, {'english': 'Item 2', 'french': 'Item 2 (fr translated)'}]], 
    'id': 'field_1', 
    'label': {'english': 'Items', 'french': 'Items (fr translated)'}, 
    'type': 'choicefield'}, 
{'choices': None, 
    'id': 'field_2', 
    'label': {'english': 'Keywords', 'french': 'Keywords (fr translated)'}, 
    'type': 'textfield'}, 
{'choices': None, 
    'id': 'field_3', 
    'label': {'english': 'Agree?'}, 
    'type': 'checkbox'}] 
+1

Спасибо за быстрый ответ, который работает и намного быстрее, чем то, что я делал .... :) – Adeel

+1

@AdeelYounas: Обратите внимание, что я не использовал 'copy.deepcopy()' здесь, потому что ваша структура выборки не нужно это. Если какое-либо из значений поля является mutables, и мы * не * меняем его в этом коде, вам может понадобиться создать глубокую копию в любом случае (вместо понимания списка с помощью 'dict.copy()' создание мелких копий). По сути, значение 'choice' заменяется новым списком в коде, создающим многоязычные словари для этикеток. –

+1

Да, на данный момент его не требуется, но изменит его на deepcopy, спасибо – Adeel

Смежные вопросы