Как мне инициализировать словарь пустых списков в Python?
Моя попытка программно создать словарь списков не позволяет мне обращаться к ключам словаря по отдельности. Всякий раз, когда я создаю словарь списков и пытаюсь добавить к одному ключу, все они обновляются. Вот очень простой тестовый пример:
data = {} data = data.fromkeys(range(2),[]) data[1].append('hello') print data
from collections import defaultdict data = defaultdict(list) data[1].append('hello')
Таким образом, ключи не нужно инициализировать пустыми списками заранее. Вместо этого defaultdict() объект вызывает предоставленную ему заводскую функцию каждый раз, когда осуществляется доступ к ключу, который еще не существует. Итак, в этом примере попытка получить доступ к data[1] срабатывает data[1] = list() внутренне, присваивая этому ключу новый пустой список в качестве его значения.
Исходный код с .fromkeys общим одним (изменяемым) списком. Аналогично,
alist = [1] data = dict.fromkeys(range(2), alist) alist.append(2) print(data)
Все значения относятся только к одному экземпляру, поэтому обычно не имеет смысла, чтобы value был изменяемым объектом, таким как пустой список.
Другой вариант - использовать dict.setdefault() метод, который извлекает значение для ключа после первой проверки его существования и установки значения по умолчанию, если оно не существует. .append затем можно вызвать результат:
data = {} data.setdefault(1, []).append('hello')
Наконец, чтобы создать словарь из списка известных ключей и заданного списка "шаблонов" (где каждое значение должно начинаться с одних и тех же элементов, но представлять собой отдельный список), используйте понимание словаря и скопируйте исходный список:
alist = [1] data = {key: alist[:] for key inrange(2)}
>>> keys = ['a','b','c'] >>> value = [0, 0] >>> {key: list(value) for key in keys} {'a': [0, 0], 'b': [0, 0], 'c': [0, 0]}
Ответ 4
Этот ответ здесь , чтобы объяснить это поведение всем, кто сбит с толку результатами, которые они получают при попытке создать экземпляр dict with fromkeys() с изменяемым значением по умолчанию в этом dict.
Рассмотрим:
#Python 3.4.3 (default, Nov 17 2016, 01:08:31)
# start by validating that different variables pointing to an # empty mutable are indeed different references. >>> l1 = [] >>> l2 = [] >>> id(l1) 140150323815176 >>> id(l2) 140150324024968
таким образом, любое изменение на l1 не повлияет l2 и наоборот. это было бы верно для любого изменяемого параметра на данный момент, включая dict.
# create a new dict from an iterable of keys >>> dict1 = dict.fromkeys(['a', 'b', 'c'], []) >>> dict1 {'c': [], 'b': [], 'a': []}
это может быть удобной функцией. здесь мы присваиваем каждому ключу значение по умолчанию, которое также является пустым списком.
# the dict has its own id. >>> id(dict1) 140150327601160
# but look at the ids of the values. >>> id(dict1['a']) 140150323816328 >>> id(dict1['b']) 140150323816328 >>> id(dict1['c']) 140150323816328
Действительно, все они используют один и тот же ref! Изменение одного - это изменение всех, поскольку фактически это один и тот же объект!
Действительно, все значения одинаковы (и единственные!) None. Теперь давайте выполним итерацию одним из множества способов через dict и изменим значение.