добавить несколько значений для одного ключа в словаре
Я новичок в python, и у меня есть список лет и значений за каждый год. То, что я хочу сделать, это проверить, существует ли уже год в словаре, и если это так, добавьте значение в этот список значений для конкретного ключа.
Так, например, у меня есть список лет и у меня есть одно значение за каждый год:
2010
2
2009
4
1989
8
2009
7
То, что я хочу сделать, это заполнить словарь с годами как ключами и этими цифрами в качестве значений. Однако, если в 2009 году я перечислял дважды, я хочу добавить это второе значение в свой список значений в этом словаре, поэтому хочу:
2010: 2
2009: 4, 7
1989: 8
Сейчас у меня есть следующее:
d = dict()
years = []
(get 2 column list of years and values)
for line in list:
year = line[0]
value = line[1]
for line in list:
if year in d.keys():
d[value].append(value)
else:
d[value] = value
d[year] = year
Ответы
Ответ 1
Если я могу перефразировать ваш вопрос, то вам нужен словарь с годами в виде ключей и массив для каждого года, содержащий список значений, связанных с этим годом, не так ли? Вот как я это сделаю:
years_dict = dict()
for line in list:
if line[0] in years_dict:
# append the new number to the existing array at this slot
years_dict[line[0]].append(line[1])
else:
# create a new array in this slot
years_dict[line[0]] = [line[1]]
То, что вам должно получиться в years_dict, - это словарь, который выглядит следующим образом:
{
"2010": [2],
"2009": [4,7],
"1989": [8]
}
В целом, это плохая практика программирования для создания "параллельных массивов", где элементы неявно связаны друг с другом с помощью одного и того же индекса, а не являются надлежащими дочерними элементами контейнера, который охватывает их обоих.
Ответ 2
Лучше всего использовать collections.defaultdict
(добавлен в Python 2.5). Это позволяет указать тип объекта по умолчанию отсутствующего ключа (например, list
).
Поэтому вместо того, чтобы создавать ключ, если он не существует первым, а затем добавляется к значению ключа, вы вырезаете среднего человека и просто добавляете к несуществующим клавишам, чтобы получить желаемый результат.
Быстрый пример использования ваших данных:
>>> from collections import defaultdict
>>> data = [(2010, 2), (2009, 4), (1989, 8), (2009, 7)]
>>> d = defaultdict(list)
>>> d
defaultdict(<type 'list'>, {})
>>> for year, month in data:
... d[year].append(month)
...
>>> d
defaultdict(<type 'list'>, {2009: [4, 7], 2010: [2], 1989: [8]})
Таким образом, вам не нужно беспокоиться о том, видели ли вы цифру, связанную с годом или нет. Вы просто добавляете и забываете, зная, что отсутствующий ключ всегда будет списком. Если ключ уже существует, он будет просто добавлен.
Ответ 3
Вы можете использовать setdefault
.
for line in list:
d.setdefault(year, []).append(value)
Это работает, потому что setdefault возвращает список, а также устанавливает его в словаре, а поскольку список изменен, добавление к версии, возвращаемой setdefault, аналогично добавлению к версии внутри самого словаря. Если это имеет смысл.
Ответ 4
d = {}
# import list of year,value pairs
for year,value in mylist:
try:
d[year].append(value)
except KeyError:
d[year] = [value]
Путь Python - легче получить прощение, чем запросить разрешение!
Ответ 5
Вот альтернативный способ сделать это с помощью оператора not in
:
# define an empty dict
years_dict = dict()
for line in list:
# here define what key is, for example,
key = line[0]
# check if key is already present in dict
if key not in years_dict:
years_dict[key] = []
# append some value
years_dict[key].append(some.value)
Ответ 6
Это проще, если вы получите эти значения в список кортежей. Для этого вы можете использовать нарезку списка и функцию zip.
data_in = [2010,2,2009,4,1989,8,2009,7]
data_pairs = zip(data_in[::2],data_in[1::2])
Zip принимает произвольное количество списков, в этом случае четные и нечетные записи data_in
, и складывает их в кортеж.
Теперь мы можем использовать метод setdefault
.
data_dict = {}
for x in data_pairs:
data_dict.setdefault(x[0],[]).append(x[1])
setdefault
берет ключ и значение по умолчанию и возвращает либо связанное значение, либо если нет текущего значения, значение по умолчанию. В этом случае мы либо получим пустой или заполненный список, который затем добавим текущее значение.
Ответ 7
Если вы хотите (почти) однострочник:
from collections import deque
d = {}
deque((d.setdefault(year, []).append(value) for year, value in source_of_data), maxlen=0)
Используя dict.setdefault
, вы можете инкапсулировать идею "проверить, существует ли ключ, и создать новый список, если нет" в одном вызове. Это позволяет вам написать выражение генератора, которое будет использоваться deque
настолько эффективно, насколько это возможно, так как длина очереди установлена на ноль. Deque будет немедленно отброшен, и результат будет в d
.
Это то, что я просто сделал для развлечения. Я не рекомендую использовать это. Есть время и место для использования произвольных итераций через deque, и это определенно не так.