Вычитание словарей (фильтрация)
Есть 2 словаря
dic1 = {
'NAME': 'JACK',
'AGE': '20',
'ID': '10',
'FK_ID': '35',
'CONST_ID': '141',
'CODE_SK': 'LAST'
}
dic2 = {
'CODE': 'ID, FK_ID',
'CONST': 'CONST_ID'
}
Нужно из первого словаря (dic1) исключить пары ключ/значение, которые есть во втором словаре как значение (dic2), при этом значение во втором словаре могут быть через запятую, которые в первом являются ключом. Должно получится так:
dic3 = {
'NAME': 'JACK',
'AGE': '20',
'CODE_SK': 'LAST'
}
Пробовал словарь преобразовать в set и вычитать, но такой метод не сработал.
Ответы (2 шт):
Предлагаю сначала сгенерировать список ключей, которые должны быть удалены из словаря. А потом отфильтровать ключи словаря по условию.
Для получения списка ключей можно проитерировать значения словаря и разделить каждое по запятой с помощью метода split. Лишние пробельные символы можно удалить с помощью strip.
Пример:
# ['ID', 'FK_ID', 'CONST_ID']
keys = [subkey.strip() for value in dic2.values() for subkey in value.split(',')]
result = {key: value for key, value in dic1.items() if key not in keys}
print(result)
stdout:
{'NAME': 'JACK', 'AGE': '20', 'CODE_SK': 'LAST'}
Еще это можно сделать через удаление ключей из словаря (или его копии, если оригинал надо сохранить):
for v in dic2.values():
for k in v.split(','):
del dic1[k.strip()]
Правда если в dic2 будут ключи, которых нет в dic1 код выдаст ошибку. Это можно обойти если вместо del использовать pop. То есть примерно так:
dic2 = {'CODE': 'ID, FK_ID',
'CONST': 'CONST_ID, test_key'}
[dic1.pop(k.strip(), None) for v in dic2.values() for k in v.split(',')]
print(dic1) # {'NAME': 'JACK', 'AGE': '20', 'CODE_SK': 'LAST'}
Такой способ может быть оправдан если dic1 содержит большое количество ключей и вместо того, чтобы проверять в цикле каждый ключ можно пройти циклом по dic2 и удалить совпадения.