Почему исходный список не копируется?
Почему не скопировался исходный список?
def em(list_data):
with open('test2.json','r',encoding='utf-8') as file_json:
data_json = []
for item in file_json:
try:
data_json.append(json.loads(item))
except Exception as err:
print(err)
data_result = []
copy_list_data = list_data.copy()
for data in list_data:
for item in data_json:
if data['idnp'] in item[0] or data['idnp'] == item[0]:
data_result.append(item)
data.clear()
break
for data in list_data:
if data.get('idnp'):
data_result.append(list(data.values()))
print(copy_list_data)
В первом цикле я достаю из файла все строки. Во втором цикле я добавляю в нужном мне порядке элементы в список data_result и затем то что добавил очищаю. И в list_data остается уже очищенный список и затем то что осталось я добавляю в окончательный список.
Но почему в переменной copy_list_data после того как я очистил список list_data сохраняется очищенный список? Я же скопировал исходный список до очищения
А можно как-то по другому написать данную функцию, без дополнительных циклов и переменных?
Объясню, что мне нужно: В файле находятся строки такого вида ["S18D8402100DY", "\u041a\u0410\u041f\u041e\u0422", "Chery", "0", "15", 11604.06, "BRAN", 11922.12, "TKUC", 11951.53, "FRZA", "None"]
А в исходном списке list_data есть словари и в каждый словарь имеет уникальный артикул, ключ idnp, пример {'idnp': 'F3102000C1', 'name': '', 'brand': 'LIFAN', 'min_count': 0, 'max_time_delivery': 15, 'count_sell': nan}
В исходном списке находятся словари для парсинга, в результате, после парсинга, данные сохраняются в json'e в файл. Далее я вызываю эту функцию. Но данные которые в исходном списке и файле расходятся. В файле может быть такое, что некоторых записей нету. Поэтому мне нужно получить список, в котором будут недостающие записи из исходного списка. Как это сделать?
Ответы (1 шт):
Проблема в том, что вы делаете "поверхностную" копию сложной структуры данных. Под сложной имеется ввиду список, элементами которого являюся словари. Таким образом, в новый список копируются только ссылки на эти самые словари, которые вы потом очищаете.
Эта проблема решается использованием "глубокого" копирования - создание реальных новых объектов.
from copy import deepcopy
l1 = [['a', 'b'], ['c', 'd']]
l1_c = l1.copy()
l1_dc = deepcopy(l1)
# оригинал и копия ссылаются на один объект в памяти
assert(id(l1[0]) == id(l1_c[0]))
# оригинал и глубокая копия ссылаются на разные объекты в памяти
assert(id(l1[0]) != id(l1_dc[0]))
for l in l1:
l.clear()
print(l1_c) # -> [[], []]
print(l1_dc) # -> [['a', 'b'], ['c', 'd']]