Слияние данных из 2-х списков со словарями по одинаковому ключу и его значению
Из разных сервисов получаю 2 списка с пользовательскими данными в виде словарей, в обоих списках в словарях есть одинаковый ключ 'user_id', количество записей в списках может не совпадать, в списке 'current_list' (данные об активных пользователях из ldap) записей о пользователях будет всегда либо меньше либо равное количеству в списке 'users_list':
users_list = [
{'user_id': '24638', 'phone_name': 'p24638', "some_key": "some_value", ...},
...,
{'user_id': '03283', 'phone_name': 'p03283', "some_key": "some_value", ...},
{'user_id': '01595', 'phone_name': 'p01595', "some_key": "some_value", ...}
]
current_list = [
{'user_id': '03283', 'display_name': 'Z.Oleg', 'mail': '[email protected]', ...},
...,
{'user_id': '01595', 'display_name': 'S.Mikhail', 'mail': '[email protected]', ...}
]
Необходимо дополнить данные пользователя в списке 'current_list' данными из первого списка при совпадении значений ключа 'user_id'. Самое простое решение: пройтись 2 циклами по спискам и обновить данные:
for i in current_list:
for j in users_list:
if i["user_id"] == j["user_id"]:
i.update(
{
"phone_name": j["phone_name"],
"some_key" : j["some_value"]
}
)
но тогда суммарное количество иттераций будет i*j, а списки могут быть большими и каждый содержать по несколько десятков тысяч записей. Какие еще могут быть варианты смерджить данные, желательно без использования сторонних библиотек?
Ответы (1 шт):
Можно два списка превратить в два словаря с ключем в виде user_id. Потом провести слияние через dict.update(). И преобразовать словарь в список по значениям. Будет около 3*N (спасибо GrAnd) операций.
users_list = [
{'user_id': '24638', 'phone_name': 'p24638', "some_key": "some_value", },
{'user_id': '03283', 'phone_name': 'p03283', "some_key": "some_value", },
{'user_id': '01595', 'phone_name': 'p01595', "some_key": "some_value", }
]
current_list = [
{'user_id': '03283', 'display_name': 'Z.Oleg', 'mail': '[email protected]', },
{'user_id': '01595', 'display_name': 'S.Mikhail', 'mail': '[email protected]', }
]
current_dict = {r['user_id']: r for r in current_list}
for k in users_list:
if current_dict.get(k['user_id']):
current_dict[k['user_id']].update(k)
else: # Если нужно добавить недостающего пользователя
current_dict[k['user_id']] = k
current_list = list(current_dict.values())
В current_list:
[{'user_id': '03283', 'display_name': 'Z.Oleg', 'mail': '[email protected]', 'phone_name': 'p03283', 'some_key': 'some_value'}, {'user_id': '01595', 'display_name': 'S.Mikhail', 'mail': '[email protected]', 'phone_name': 'p01595', 'some_key': 'some_value'}, {'user_id': '24638', 'phone_name': 'p24638', 'some_key': 'some_value'}]