@Mikkkch

Как упростить код с циклами for?

Есть кусок кода, основной целью которого является осуществление проверки вхождения лишних элементов путем сопоставления главного списка и списка с данными.

columns = [column.name for column in cls.storing_table.columns]
passed_parameters = data.dict()

for parameter in passed_parameters:
    assert parameter in columns, \
        f'The table called {cls.storing_table.name} does not contain the column called {parameter}.'

for column in columns:
    assert column in passed_parameters, \
        f'The list of arguments passed to the {cls.storing_table.name} ' \
        f'table contains no argument for the {column} column.'


Мы проходим по названиям колонок из таблицы данных, после чего обращаемся к методу dict экземпляра схемы, содержащей поля, которые впоследствии будут распакованы в функцию insert. Для того, чтобы все отработало безопасно мы осуществляем проверку на наличие в списке переданных параметров(ключей словаря) лишних элементов. Если, например, в таблице две колонки id и username, то передать схему с параметрами id, username и phone_number не получится. Так же не получится передавать схему с отсутствием необходимых параметров, чтобы на всякий случай перестраховаться с ограничением NOT NULL. Меня не совсем радует эта громоздкая реализация с двумя циклами. Возможно вы знаете как можно бы было ее упростить?
  • Вопрос задан
  • 93 просмотра
Решения вопроса 1
dunmaksim
@dunmaksim
Технический писатель
Я бы попробовал обходной путь. Получите список полей таблицы как кортеж и список переданных в данных полей, после чего пройдитесь по названиям полей данных, переданных пользователем. Добавьте в список валидных полей только те, что есть в таблице:

columns = list(column.name for column in cls.storing_table.columns)
data_fields = data.dict()
validated_data_fields = []

for data_field in data_fields:
    if data_field in columns: # Внутри скрытый for
        validated_data_fields.append(data_field)


Попробуйте то же самое решение с применением множеств (внутри тоже два скрытых for'а):

columns = set(list(column.name for column in cls.storing_table.columns))
data_fields = set(data.dict())

validated_fields = list(data_fields.intersection(columns)) # Вот тут скрытые for'ы


Не используйте инструкцию assert в коде, выполняющемся на Production, потому что интерпретатор Python выбрасывает все строки с этим оператором при построении оптимизированного байт-кода (99,999% случаев на Production).
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@dmshar
Если у вас есть два объекта, один - [id, username,address], второй - {id, username и phone_number] и вам надо получить новый объект, состоящий из элементов гарантированно присутствующих в обоих входных объектов, то делается это с помощью пересечения. Чуть сложнее, но тоже в полтора действия находятся элементы, присутствующие только в одном из двух объектов. А дальше - делайте с этими полученными множествами что хотите, хоть схему генерируйте, хоть запросы.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы