Вложенный диктонарий в python

#python

#python

Вопрос:

Я пытаюсь обновить значения во внутреннем диктонарии, но он обновляется в обоих, я много пробовал, но все еще сталкиваюсь с той же проблемой. Заранее спасибо.

 arr = [1,2]
d_int = {'a':False, 'e':False, 'i':False, 'o':False, 'u':False}
d_main ={i : d_int for i in range(len(arr))}
print(d_main)
d_main[0]['a'] = True
d_main[1]['i'] = True
print(d_main)
  

Результат:

 {0: {'a': True, 'e': False, 'i': True, 
     'o': False, 'u': False}, 
 1: {'a': True, 'e': False, 'i': True, 
     'o': False, 'u': False}
}
  

Нужно что-то вроде этого:

 {0: {'a': True, 'e': False, 'i': False,
     'o': False, 'u': False},
 1: {'a': False, 'e': False, 'i': True,
     'o': False, 'u': False}
}
  

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

1. Измените d_int на d_int.copy() , и вы получите свой результат. Вы ссылаетесь на один и тот же объект.

2. Предупреждение: Если у вас есть вложенные объекты, такие как dict в dict, вам также необходимо скопировать их

Ответ №1:

Если вы новичок без какого-либо опыта программирования на каком-либо языке программирования, для понимания причины возникновения проблемы вам лучше сначала узнать, что такое указатель на языке программирования C.


copy.deepcopy является лучшим. dict.copy у меня такая же проблема с глубоким вложенным dict. следующим образом.

 a = {"1": {"2": 2, "3": 3}, "4":4}

c = {1:a.copy()}
b = {1:a.copy()}

c[1]['1']['2'] = 5
c[1]['4'] = 40

print(c)
# {1: {'1': {'3': 3, '2': 5}, '4': 40}}
print(b)
# {1: {'1': {'3': 3, '2': 5}, '4': 4}}
  

Но copy.deepcopy он хорошо работает с глубоко вложенным dict.

 from copy import deepcopy

a = {"1": {"2": 2, "3": 3}, "4":4}

c = {1: deepcopy(a)}
b = {1: deepcopy(a)}

c[1]['1']['2'] = 5
c[1]['4'] = 40

print(c)
# {1: {'1': {'2': 5, '3': 3}, '4': 40}}

print(b)
# {1: {'1': {'2': 2, '3': 3}, '4': 4}}
  

На самом деле, эта проблема возникает не только с вложенным dict, но и с другими типами, такими как вложенный список, класс со свойством dict и так далее, и copy.deepcopy работает хорошо.

Ответ №2:

Это потому, что все значения d_main ссылаются на один и тот же объект dict d_int . Изменения в любом из них отразятся на всех ссылках. Читать далее

Чтобы избежать проблемы, убедитесь, что вы создали новую копию объекта dict во время понимания списка, используя методы копирования, такие как .copy .

 arr = [1,2]
d_int = {'a':False, 'e':False, 'i':False, 'o':False, 'u':False}
d_main ={i : d_int.copy() for i in range(len(arr))} #modified.
print(d_main)
d_main[0]['a'] = True
d_main[1]['i'] = True
print(d_main)
#Output:
{0: {'a': True, 'e': False, 'i': False, 'o': False, 'u': False}, 1: {'a': False, 'e': False, 'i': True, 'o': False, 'u': False}}
  

Ответ №3:

Короткое решение: измените d_int на d_int.copy() и вы получите свой результат. Вы ссылаетесь на один и тот же объект. Посмотрите на разницу в идентификаторе в этих двух случаях:

Пример 1 (ваша попытка)

 arr = [1,2]
d_int = {'a':False, 'e':False, 'i':False, 'o':False, 'u':False}
d_main ={i : d_int for i in range(len(arr))}
print(list(map(id,d_main.values())))
  

ВОЗВРАТ:

 [140545244867248, 140545244867248] # <-- they are the same
  

Пример 2 (возможный обходной путь)

 arr = [1,2]
d_int = {'a':False, 'e':False, 'i':False, 'o':False, 'u':False}
d_main ={i : d_int.copy() for i in range(len(arr))} # <-- .copy() added
print(list(map(id,d_main.values())))
  

ВОЗВРАТ:

 [140545244796464, 140545244798480]