python добавляет в список в цикле for

#python #for-loop

Вопрос:

ниже вы можете увидеть фрагмент упрощенного кода, но проблемы, с которыми я сталкиваюсь, хорошо видны. У меня есть диктант, заполненный данными. Это из повторного запроса на получение. Поэтому я не могу изменить структуру. Я хочу добавить вывод печати(тест(данные,x)) в список, но список содержит другие данные. Когда я посмотрел на эту проблему, я увидел, что мне пришлось использовать .copy()/list (), но я не могу найти способ заставить это работать.

Новый код(после некоторых возможных улучшений)

 data = {"datasource": "InfluxDB", "gridPos": {"h": 4, "w": 3, "x": 3, "y": 14}, "id": 80, "targets": [{"measurement": "database"}, {"measurement": "database"}],"title": "Name"} test_list = []  def test(data,database):  data = data.copy()  data['gridPos']['x']  = data['gridPos']['w']   1  data['gridPos']['y']  = data['gridPos']['h']   1  data['id']  = 1  data['targets'][0]['measurement']  = str(database)   return data  for x in range(0,10):  data = test(data,x)  test_list.append(data.copy())  test_list  
 data = {"datasource": "InfluxDB", "gridPos": {"h": 4, "w": 3, "x": 3, "y": 14}, "id": 80, "targets": [{"measurement": "database"}, {"measurement": "database"}],"title": "Naam"} test_list = []  def test(data,database):  data['gridPos']['x']  = data['gridPos']['w']   1  data['gridPos']['y']  = data['gridPos']['h']   1  data['id']  = 1  data['targets'][0]['measurement']  = str(database)   return data  for x in range(0,10):  print(test(data,x))  test_list.append(test(data,x).copy())  print(test_list)   

печать(тест(данные,x)) (в первом цикле)

 {'datasource': 'InfluxDB', 'gridPos': {'h': 4, 'w': 3, 'x': 7, 'y': 19}, 'id': 81, 'targets': [{'measurement': 'database0'}, {'measurement': 'database'}], 'title': 'Name'} {'datasource': 'InfluxDB', 'gridPos': {'h': 4, 'w': 3, 'x': 15, 'y': 29}, 'id': 83, 'targets': [{'measurement': 'database001'}, {'measurement': 'database'}], 'title': 'Name'} {'datasource': 'InfluxDB', 'gridPos': {'h': 4, 'w': 3, 'x': 23, 'y': 39}, 'id': 85, 'targets': [{'measurement': 'database00112'}, {'measurement': 'database'}], 'title': 'Name'} {'datasource': 'InfluxDB', 'gridPos': {'h': 4, 'w': 3, 'x': 31, 'y': 49}, 'id': 87, 'targets': [{'measurement': 'database0011223'}, {'measurement': 'database'}], 'title': 'Name'} {'datasource': 'InfluxDB', 'gridPos': {'h': 4, 'w': 3, 'x': 39, 'y': 59}, 'id': 89, 'targets': [{'measurement': 'database001122334'}, {'measurement': 'database'}], 'title': 'Name'} {'datasource': 'InfluxDB', 'gridPos': {'h': 4, 'w': 3, 'x': 47, 'y': 69}, 'id': 91, 'targets': [{'measurement': 'database00112233445'}, {'measurement': 'database'}], 'title': 'Name'} {'datasource': 'InfluxDB', 'gridPos': {'h': 4, 'w': 3, 'x': 55, 'y': 79}, 'id': 93, 'targets': [{'measurement': 'database0011223344556'}, {'measurement': 'database'}], 'title': 'Name'} {'datasource': 'InfluxDB', 'gridPos': {'h': 4, 'w': 3, 'x': 63, 'y': 89}, 'id': 95, 'targets': [{'measurement': 'database001122334455667'}, {'measurement': 'database'}], 'title': 'Name'} {'datasource': 'InfluxDB', 'gridPos': {'h': 4, 'w': 3, 'x': 71, 'y': 99}, 'id': 97, 'targets': [{'measurement': 'database00112233445566778'}, {'measurement': 'database'}], 'title': 'Name'} {'datasource': 'InfluxDB', 'gridPos': {'h': 4, 'w': 3, 'x': 79, 'y': 109}, 'id': 99, 'targets': [{'measurement': 'database0011223344556677889'}, {'measurement': 'database'}], 'title': 'Name'}  

печать(список тестов)

 [{'datasource': 'InfluxDB',  'gridPos': {'h': 4, 'w': 3, 'x': 83, 'y': 114},  'id': 82,  'targets': [{'measurement': 'database00112233445566778899'},  {'measurement': 'database'}],  'title': 'Name'},  {'datasource': 'InfluxDB',  'gridPos': {'h': 4, 'w': 3, 'x': 83, 'y': 114},  'id': 84,  'targets': [{'measurement': 'database00112233445566778899'},  {'measurement': 'database'}],  'title': 'Name'},  {'datasource': 'InfluxDB',  'gridPos': {'h': 4, 'w': 3, 'x': 83, 'y': 114},  'id': 86,  'targets': [{'measurement': 'database00112233445566778899'},  {'measurement': 'database'}],  'title': 'Name'},  {'datasource': 'InfluxDB',  'gridPos': {'h': 4, 'w': 3, 'x': 83, 'y': 114},  'id': 88,  'targets': [{'measurement': 'database00112233445566778899'},  {'measurement': 'database'}],  'title': 'Name'},  {'datasource': 'InfluxDB',  'gridPos': {'h': 4, 'w': 3, 'x': 83, 'y': 114},  'id': 90,  'targets': [{'measurement': 'database00112233445566778899'},  {'measurement': 'database'}],  'title': 'Name'},  {'datasource': 'InfluxDB',  'gridPos': {'h': 4, 'w': 3, 'x': 83, 'y': 114},  'id': 92,  'targets': [{'measurement': 'database00112233445566778899'},  {'measurement': 'database'}],  'title': 'Name'},  {'datasource': 'InfluxDB',  'gridPos': {'h': 4, 'w': 3, 'x': 83, 'y': 114},  'id': 94,  'targets': [{'measurement': 'database00112233445566778899'},  {'measurement': 'database'}],  'title': 'Name'},  {'datasource': 'InfluxDB',  'gridPos': {'h': 4, 'w': 3, 'x': 83, 'y': 114},  'id': 96,  'targets': [{'measurement': 'database00112233445566778899'},  {'measurement': 'database'}],  'title': 'Name'},  {'datasource': 'InfluxDB',  'gridPos': {'h': 4, 'w': 3, 'x': 83, 'y': 114},  'id': 98,  'targets': [{'measurement': 'database00112233445566778899'},  {'measurement': 'database'}],  'title': 'Name'},  {'datasource': 'InfluxDB',  'gridPos': {'h': 4, 'w': 3, 'x': 83, 'y': 114},  'id': 100,  'targets': [{'measurement': 'database00112233445566778899'},  {'measurement': 'database'}],  'title': 'Name'}]  

Комментарии:

1. в чем проблема? И как должен выглядеть ваш целевой список?

2. Что именно вы пытаетесь получить в результате?

3. я хочу получить список диктов (со значениями, которые отображаются в печати(тест(данные,x)))

Ответ №1:

Ваша test функция преобразуется data , и вы вызываете ее дважды — один раз для печати и один раз для добавления, поэтому она преобразует словарь дважды на каждой итерации. Кроме того, copy создается только неглубокая копия словаря, но вам нужна глубокая копия, потому что она содержит вложенные словари и списки.

Чтобы исправить это, import copy и измените эту строку

 test_list.append(test(data,x).copy())  

Для

 test_list.append(copy.deepcopy(data)) # data has already been transformed so no need to call `test` again  

Или лучше, измените структуру так, чтобы ваша функция не имела побочных эффектов:

 def test(data,database):  data = copy.deepcopy(data)  data['gridPos']['x']  = data['gridPos']['w']   1  data['gridPos']['y']  = data['gridPos']['h']   1  data['id']  = 1  data['targets'][0]['measurement']  = str(database)   return data  for x in range(10):  data = test(data,x)  print(data)  test_list.append(data)  

В общем, для функции чище избегать преобразования своих параметров и вместо этого возвращать новое значение. Если вам действительно нужна функция для преобразования объекта на месте, то, вероятно, избегайте также возврата того же объекта, так как это может привести к путанице.

Комментарии:

1. Когда я делаю то, что ты говоришь, ничего не меняется.

2. Приносим извинения, см. отредактированную версию. Была еще одна проблема, которая заключается в том, что вам нужно сделать глубокую копию словаря.