Невозможно обновить одно значение во вложенном словаре

#python #dictionary #data-structures

Вопрос:

После создания такого словаря {'key': {'key': {'key': 'value'}}} я столкнулся с проблемами , пытаясь установить значение для ключа более высокой глубины. После обновления одного из этих значений также были обновлены значения для остальных значений (других ключей).

Вот мой код на Python:

 times = ["09:00", "09:30", "10:00", "10:30"]
courts = ["1", "2"]

daytime_dict = dict.fromkeys(times)
i = 0
for time in times:
    daytime_dict[times[i]] = dict.fromkeys(["username"])
    i  = 1

courts_dict = dict.fromkeys(courts)
k = 0
for court in courts:
    courts_dict[courts[k]] = daytime_dict
    k  = 1

day_info = [('name', '09:00', 1), ('name', '09:30', 1)]
for info in day_info:
    info_court = str(info[2])
    time = info[1]
    # Here I am trying to set the value for courts_dict['1']['09:00']["username"] to be 'name', 
    # but the value for courts_dict['2']['09:00']["username"] and courts_dict['3']['09:00']["username"] is also set to 'name'
    # What am I doing wrong? How can I only update the value for where the court is '1'?
    courts_dict[info_court][time]["username"] = info[0] 
 

Я хочу получить это:

 {'1': {'09:00': {'username': 'name'},
       '09:30': {'username': 'name'},
       '10:00': {'username': None},
       '10:30': {'username': None}},
 '2': {'09:00': {'username': None},
       '09:30': {'username': None},
       '10:00': {'username': None},
       '10:30': {'username': None}}
 

Но я понимаю это:

 {'1': {'09:00': {'username': 'name'},
       '09:30': {'username': 'name'},
       '10:00': {'username': None},
       '10:30': {'username': None}},
 '2': {'09:00': {'username': 'name'},
       '09:30': {'username': 'name'},
       '10:00': {'username': None},
       '10:30': {'username': None}}
 

(Смотрите, как court_dict['2']['09:00']['username'] и court_dict['2']['09:30']['username'] обновляются оба, когда я хочу обновить значения только из court_dict['1'] )

Логически я не могу понять, почему оба значения обновляются при обновлении courts_dict (как я сделал в последней строке кода), а не только одно. С тех пор info_court "1" я думал "username" , что будет обновлено только для этого суда.

Что я сделал не так?

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

1. скорее всего, вы ссылаетесь на словарь, а не делаете копию.

2. попробуйте это и посмотрите, исчезнет ли проблема courts_dict[courts[k]] = daytime_dict.copy()

3. Это не сработало, я получил те же результаты, что и раньше

Ответ №1:

Логически я не могу понять, почему оба значения обновляются при обновлении courts_dict

Для объектов словаря, которые вы используете, вы присваиваете те же ссылки на объекты, что и значения, поэтому вы видите «оба значения обновлены». Возможно, вам захочется переработать свой код с помощью copy или deepcopy :

https://docs.python.org/3/library/copy.html

Операторы присваивания в Python не копируют объекты, они создают привязки между целевым объектом и объектом. Для коллекций, которые являются изменяемыми или содержат изменяемые элементы, иногда требуется копия, чтобы можно было изменить одну копию, не изменяя другую.