#python
Вопрос:
Итак, дан список словарей в следующем формате:
[
{
'prod_instance': 'AEIS_PWH_SP1',
'testing_instance': 'AEIS_PWH_DA1',
'project_adm': 'scisae',
'vdb': 'aPWH - cpi',
'db_name': 'cpi'
},
{
'prod_instance': 'AEIS_PWH_SP1',
'testing_instance': 'AEIS_PWH_DA1',
'project_adm': 'scisae',
'vdb': 'aPWH - aeis',
'db_name': 'asis'
}
]
Я хотел бы объединить словари, если prod_instance
, testing_instance
, и project_adm
равны.
т. е. ожидаемый результат приведенного выше примера
[
{
'prod_instance': 'AEIS_PWH_SP1',
'testing_instance': 'AEIS_PWH_DA1',
'project_adm': 'scisae',
'data_sources': [
{
'vdb': 'aPWH - cpi',
'db_name': 'cpi'
},
{
'vdb': 'aPWH - aeis',
'db_name': 'asis'
}
]
}
]
Конечно, я могу сделать это с помощью двойного for
цикла, но (1) это O(n 2) и (2) это долго и некрасиво.
Может ли кто-нибудь придумать более элегантный способ?
Комментарии:
1. Можете ли вы предоставить свой код
2. Это имеет значение? Как упоминалось в конце моего вопроса, я знаю, что двойной цикл for работает, но мне это не нравится. Оптимальный ответ, если таковой имеется, в любом случае будет работать совсем иначе, чем мой нынешний подход. Это похоже на то, как если бы я просил алгоритм быстрой сортировки, когда я использую сортировку по пузырькам. Так какой смысл публиковать то, что у меня есть прямо сейчас?
Ответ №1:
Это то, чего ты хочешь?
data = [
{
'prod_instance': 'AEIS_PWH_SP1',
'testing_instance': 'AEIS_PWH_DA1',
'project_adm': 'scisae',
'vdb': 'aPWH - cpi',
'db_name': 'cpi'
},
{
'prod_instance': 'AEIS_PWH_SP1',
'testing_instance': 'AEIS_PWH_DA1',
'project_adm': 'scisae',
'vdb': 'aPWH - aeis',
'db_name': 'asis'
}
]
res = {}
for i in data:
# by @blhsing: tuple is easier and more efficient than string concatenation
key = (i['prod_instance'], i['testing_instance'], i['project_adm'],)
val = {
'prod_instance': i['prod_instance'],
'testing_instance': i['testing_instance'],
'project_adm': i['project_adm'],
'data_sources': []
}
data_sources = {
'vdb': i['vdb'],
'db_name': i['db_name']
}
res.setdefault(key, val)
res[key]['data_sources'].append(data_sources)
result_list = list(res.values())
print(result_list)
Комментарии:
1. Да, это отлично работает. И это O(n). Как получилось, что я пропустил ту часть, в которой я могу объединить разные ключи в один. Это может быть немного чересчур, но есть ли какая-то стенография(ы), которую я могу использовать, чтобы минимизировать этот фрагмент кода? Извините, я не слишком хорошо знаком с Python.
2. Объединение ключей подвержено столкновениям. Он сломается, если у записи есть ключи, компоненты которых в имени перекрываются с компонентами другой записи. Например, если запись имеет
prod_instance
A_B
значение «иtesting_instance
C
«, она может столкнуться с записью, которая имеетprod_instance
A
значение «иtesting_instance
B_C
«. Вряд ли это произойдет, но может произойти. Вместо этого лучше создать кортеж из составных ключей.3. @blhsing Да, цель состоит в том, чтобы использовать уникальный ключ. Существует множество методов, и сращивание символов-самый простой из них.
4. Вы правы в этом, но, к счастью, я могу гарантировать, что в данном случае ключи имеют очень строгий формат. Поэтому в данном конкретном случае столкновения должны быть невозможны.
5. @blhsing Согласен, возражений нет.