В том, что вам нужно, есть две алгоритмические задачи: найдите записи с одинаковыми значениями для США и GOOGL, а затем соедините их и сделайте так, чтобы, если в обеих записях был один и тот же ключ, их значение объединялось.
Наивный подход для первого состоит в том, чтобы иметь цикл for, который будет повторять значения списка list1, и для каждого значения повторять все значения для списка list2 - два разделенных цикла не обрежут его, вы 'нам нужно два вложенных for
цикла:
for element in list1:
for other_element in list2:
if ...:
...
Хотя этот подход будет работать и подходит для небольших списков (<1000 записей, например), он занимает некоторое количествовремя и ресурсы, которые пропорциональны квадрату размеров вашего списка, то есть для списков, которые близки к ~ 1000 элементов, мы говорим 1 миллион итераций.Если сами списки составляют 1 000 000 элементов, вычисление потребует 1 * 10 ^ 12 сравнений, а на современных компьютерах это вообще невозможно. </p>
Итак, хорошее решение - воссоздать одно из следующих значений:списки таким образом, что ключ сравнения используется в качестве хеша, что делается путем копирования списка в словарь, где ключи - это значения, которые вы хотите сравнить, и затем повторение второго списка только один раз.Поскольку словари имеют постоянное время для поиска элементов, это делает количество сравнений пропорциональным размеру вашего списка.
Вторая часть вашей задачи - сравнить, скопировать одну запись в список результатов и обновитьключи в результирующей копии, так что любые дублирующие ключи объединяются.Чтобы избежать проблем при копировании первых записей, мы безопаснее используем Python copy.deepcopy
, который гарантирует, что под-словари являются объектами, отличными от тех, что находятся в исходной записи, и останутся изолированными.
from copy import deepcopy
def merge_lists(list1, list2):
# create dictionary from list1:
dict1 = {(record["GOOG"], record["USA"]): record for record in list1}
#compare elements in list2 to those on list1:
result = {}
for record in list2:
ckey = record["GOOG"], record["USA"]
new_record = deepcopy(record)
if ckey in dict1:
for key, value in dict1[ckey].items():
if key in ("GOOG", "USA"):
# Do not merge these keys
continue
# Dict's "setdefault" finds a key/value, and if it is missing
# creates a new one with the second parameter as value
new_record.setdefault(key, {}).update(value)
result[ckey] = new_record
# Add values from list1 that were not matched in list2:
for key, value in dict1.items():
if key not in result:
result[key] = deepcopy(value)
return list(result.values())