@ruGuardian

Как правильно заполнять список словарей?

Есть один баг связанный с заполнением списка словарей.
В цикле заполняется словарь, добавляется в список. В конце итерации словарь очищается, чтобы заполниться данными на следующей итерации, но при этом очищается и список тоже. В итоге по выходу из цикла список пустой.
Python 2.7.10 (default, Sep  8 2015, 17:21:32) 
[GCC 5.1.1 20150618 (Red Hat 5.1.1-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> list = []
>>> d = {}
>>> d[1] = "1"
>>> d[2] = "2"
>>> list.append(d)
>>> d
{1: '1', 2: '2'}
>>> list
[{1: '1', 2: '2'}]
>>> d.clear()
>>> d
{}
>>> list
[{}]

ЧЯДНТ?
  • Вопрос задан
  • 225 просмотров
Решения вопроса 1
@ruGuardian Автор вопроса
ответ нашелся: порождать копию словаря и уже её пихать в список
list.append(d.copy())
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
alsopub
@alsopub
Судя по всему вы в "list" добавили ссылку на "d", затем очистили "d", он остался в "list", но уже пустой.
Обратите внимание на [{}], вместо просто [].
The method append() appends a passed obj into the existing list.

Попробуйте extend вместо append.
Ответ написан
@fireSparrow
Это не баг, так и должно быть.
Советую вам почитать про типы данных в питоне - иначе вы регулярно будете натыкаться на такие "баги".

Суть в том, что все типы данных делятся на изменяемые и неизменяемые, и они при присваивании будут вести себя по-разному.

Для изменяемых типов данных при присваивании вы НЕ копируете в переменную содержимое другой переменной, а просто передаёте в неё ссылку на ту же область памяти.

То есть, если вы делаете так:

a = {какой_то_словарь}
b = a

то и b, и a будут ссылаться на одну и ту же область памяти, и когда вы меняете один из этих словарей, второй будет меняться точно так же. Потому что на самом деле это один и тот же словарь, просто под двумя разными именами.

С методом append это работает аналогично - то есть он не делает копию словаря, добавляя её в список, а просто ТОТ ЖЕ словарь зачисляет в список.

Как уже написали выше, нужно принудительно делать копию словаря, а потом уже её вставлять в список.
Но, имхо, надёжнее использовать не copy(), а deepcopy().
Ответ написан
Комментировать
abs0lut
@abs0lut
Есть один баг

это не баг, а непонимание работы структур данных в питоне

В цикле заполняется словарь, добавляется в список. В конце итерации словарь очищается, чтобы заполниться данными на следующей итерации


а почему бы не создавать на каждой итерации новый словарь?

но при этом очищается и список тоже.


список не очищается, там же остались фигурные скобки. Это список с одним элементом
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы