Как вставить все ключи из вложенного диктанта в новый вложенный диктант?

#python #dictionary #nested

Вопрос:

Я пишу автоматизацию тестирования и должен вставить все значения из моей переменной в новый словарь, но по какой-то причине для этого всегда требуется только последнее. В чем может быть причина?

Переменная с вложенным словарем:

 {'~Manager~': {"operatorId": 'in the selection list'},
 'Candidate': {"AND":"", "operatorId": 'not in the selection list'},
  ...
 'Description': {"operatorId": 'is empty'}}
 
 def _prepare_filters_json(self, pipeline: str, filter_to_add: dict):
    new_filter = {"type": 'CONDITION', "id": 'any_id', "field": 'null',
                  "operatorId": 'null'}
    source_fields = self.ssi_get_filter_source_fields(pipeline).json_path("$.data")
    filters = self._get_filters(pipeline)
    for source_field in source_fields:
        for key in filter_to_add.keys():
            if key == source_field["descriptor"]:
                new_filter["field"] = source_field
    return self._prepare_json(pipelineId=pipeline, filter=filters)
 

source_fields возвращает список словарей. Если значение из этого списка == должно указывать ключи в моей переменной, оно должно обновить мою new_filter .

Фактический результат:

 {'field': {'descriptor': 'Description',
           'id': 'edee9a85b3fb4cb69b993139fc14ce46',
           'returnType': 'Text'},
 'id': 'any_id',
 'operatorId': 'null',
 'type': 'CONDITION'}
 

Ожидаемый результат:

 {'field': {'descriptor': '~Manager~',
           'id': 'edee9a85b3fb4cb69b993139fc123451',
           'returnType': 'Text'},
'field': {'descriptor': 'Candidate',
           'id': 'edee9a85b3fb4cb69b993139fc141111',
           'returnType': 'Text'},
'field': {'descriptor': 'Description',
           'id': 'edee9a85b3fb4cb69b993139fc14ce46',
           'returnType': 'Text'},
 'id': 'any_id',
 'operatorId': 'null',
 'type': 'CONDITION'}
 

Комментарии:

1. «Ожидаемый результат:» Этот результат не может быть создан никаким кодом. Ключи диктатора уникальны. Вот почему поиск ключей может работать детерминированно.

Ответ №1:

Я не совсем уверен, что понимаю, что вы пытаетесь сделать, однако я думаю, что вам нужен список полей, перенесенных в ваш словарь new_filter. В этом случае я бы создал список полей внутри вашего диктатора new_filter и добавил объекты в этот список, чтобы ваш вывод выглядел примерно так:

 {'fields': [{'descriptor': '~Manager~',
           'id': 'edee9a85b3fb4cb69b993139fc123451',
           'returnType': 'Text'},
{'descriptor': 'Candidate',
           'id': 'edee9a85b3fb4cb69b993139fc141111',
           'returnType': 'Text'},
{'descriptor': 'Description',
           'id': 'edee9a85b3fb4cb69b993139fc14ce46',
           'returnType': 'Text'}],
 'id': 'any_id',
 'operatorId': 'null',
 'type': 'CONDITION'}
 

Этого можно было бы достичь, выполнив что-то в соответствии с приведенными ниже:

 def _prepare_filters_json(self, pipeline: str, filter_to_add: dict):
  new_filter = {"type": 'CONDITION', "id": 'any_id', "fields": [], "operatorId": 'null'}
  source_fields = self.ssi_get_filter_source_fields(pipeline).json_path("$.data")
  filters = self._get_filters(pipeline)
  for source_field in source_fields:
    for key in filter_to_add.keys():
      if key == source_field["descriptor"]:
        new_filter["fields"].append(source_field)
  return self._prepare_json(pipelineId=pipeline, filter=filters)
 

Комментарии:

1. Это не то, чего я хочу. Я тестирую, как должно выглядеть тело в ожидаемом результате. И вы не можете добавлять к строке.

2. Ожидаемый результат невозможен, так как у вас есть 3 ключа, называемых полем, в одном дикте. Ключи в диктанте должны быть уникальными. Я превратил поля в список (не строку) в предлагаемом коде, чтобы обойти проблему использования 3 ключей с одинаковым именем и вместо этого иметь список, в который вы можете добавлять объекты. Однако, похоже, я не понимаю, чего вы пытаетесь достичь. 🙂

Ответ №2:

Я не думаю, что у вас могут быть дубликаты с тем же ключом, который вы упомянули в словаре на Python.

Я думаю, что вы предпочли бы иметь список со всеми отдельными диктантами, а не вложенный в диктант.

Вы можете делать некоторые хитрые вещи, как описано здесь.

Комментарии:

1. Но я не хочу иметь дубликатов. Я хочу взять 1 — й ключ:значение — {‘~Менеджер~’: {«Идентификатор оператора»: ‘в списке выбора’}} и выполнить свой код, добавить его в поле в new_dictionary. Затем возьмите второй ключ:значение {«Кандидат»: {«И»:»», «Идентификатор оператора»: «нет в списке выбора»} и снова выполните мой код, добавив другое поле в new_dict.

Ответ №3:

Итак, я нашел ошибку, и теперь она работает так, как ожидалось.

 def _prepare_filters_json(self, pipeline: str, filter_to_add: dict):
    new_filter = {"type": 'CONDITION', "id": 'any_id', "field": 'null',
                  "operatorId": 'null'}
    source_fields = self.ssi_get_filter_source_fields(pipeline).json_path("$.data")
    filters = self._get_filters(pipeline)
    for key in filter_to_add.keys():
        for source_field in source_fields:
          if source_field["descriptor"] == key:
            new_filter["field"] = source_field
            filters["children"].append(dict(new_filter))
    return self._prepare_json(pipelineId=pipeline, filter=filters)