Выборочное объединение двух словарей на Python - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть следующий код, который работает, но выглядит так, будто он очень вложенный. Я уверен, что есть лучший способ написать это, но я также новичок в использовании Python map / filter на lambda. Как лучше написать это, чтобы объединить 2 словаря и выбрать только интересующий нас ключ.

import copy

default_params_list = [
    {
        "abc": "some junk that we do not care",
        "time_unit": "week",
        "city": "atlanta"
    }
]

foobar_list = [
    {
        "type": "predict",
        "junk": "something we do not care",
        "start_date": "2018-09-15",
        "length": "all"
    }
]

params_list = []
for foobar in foobar_list:
    for default_params in default_params_list:
        parameters = copy.deepcopy(default_params)
        parameters.update({
            'length': foobar['length']
        })
        if(foobar.get('type', none) == 'predict'):
            if(foobar.get('start_date', none)):
                parameters.update({
                    'start_date': foobar['start_date']
                })
        if(foobar.get('type', none) == 'training'):
            if(foobar.get('end_date', none)):
                parameters.update({
                    'end_date': foobar['end_date']
                })
        params_list.append({
            'parameters': parameters
        })
print(params_list)

Выход:

[
     {'parameters': 
             {'abc': 'some junk that we do not care', 
              'time_unit': 'week', 
              'city': 'atlanta', 
              'length': 'all', 
              'start_date': '2018-09-15'}
     }
]

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Для Python 2.7 работает следующий подход.

full_dict = {}
full_dict_list = [] 
for index,val in enumerate(foobar_list):
  full_dict = dict(default_params_list[index],**val) # merge dictionaries from both the lists
  map(full_dict.pop, ['junk','type']) # remove the unwanted keys
  full_dict_list.append(full_dict)

обновление: подход без использования петель.

full_dict_list = map(lambda d1,d2:dict(d1.items()+d2.items()),foobar_list,default_params_list)
map(lambda d1:map(d1.pop,['junk','type']), full_dict_list) 
0 голосов
/ 27 апреля 2018
full_dict = {**default_params_list[0], **foobar_list[0]}
select_dict = {k: full_dict[k] for k in full_dict if k not in ['junk', 'type']}
print(select_dict) # {'abc': 'some junk that we do not care', 'time_unit': 'week', 'city': 'atlanta', 'start_date': '2018-09-15', 'length': 'all'}

Некоторые замечания:

  • Это работает только с Python 3.5 и старше, я предположил, что ваш фокус на читабельность, а не на производительность.
  • В этом фрагменте мы сначала объединяем оба слова, а затем удаляем ненужные значения. Наоборот, было бы более эффективным, но мне действительно нравится эта новая функция (PEP 448) .
  • Ваши default_params_list и foobar_list - это не диктат, а список.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...