Почему мои слова чередуются между изменчивым и неизменным? - PullRequest
0 голосов
/ 17 февраля 2020

Рассмотрим этот код

from pprint import pprint
test_dict = {}
new = {}
new['slot'] = {}
for k in range(5):
    test_dict[k] = {}
    test_dict[k].update(new)
    if k == 3:
        test_dict[k]['slot']['this should only be in 3'] = []
pprint(test_dict)
print('Round 2, without SLOT')
test_dict = {}
new = {}
for k in range(5):
    test_dict[k] = {}
    test_dict[k].update(new)
    if k == 3:
        test_dict[k]['this should only be in 3'] = []
pprint(test_dict)

С этим выводом

> python -i .\test2.py
{0: {'slot': {'this should only be in 3': []}},
 1: {'slot': {'this should only be in 3': []}},
 2: {'slot': {'this should only be in 3': []}},
 3: {'slot': {'this should only be in 3': []}},
 4: {'slot': {'this should only be in 3': []}}}
Round 2, without SLOT
{0: {}, 1: {}, 2: {}, 3: {'this should only be in 3': []}, 4: {}}

Помогите мне понять, почему в первом случае 'должно быть только ...' список появляется в каждом случае, а не во втором. Dicts неизменны, но я не понимаю, почему я получаю разные результаты.

Спасибо,

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

Вы храните один и тот же экземпляр dict, хранящийся в new['slot'], в каждой клавише test_dict:

from pprint import pprint
test_dict = {}
new = {}
new['slot'] = {}
new['slot']['id'] = id(new['slot'])
for k in range(5):
    test_dict[k] = {}
    test_dict[k].update(new)
    if k == 3:
        test_dict[k]['slot']['this should only be in 3'] = []
pprint(test_dict)

Выход

{0: {'slot': {'id': 4433735760, 'this should only be in 3': []}},
 1: {'slot': {'id': 4433735760, 'this should only be in 3': []}},
 2: {'slot': {'id': 4433735760, 'this should only be in 3': []}},
 3: {'slot': {'id': 4433735760, 'this should only be in 3': []}},
 4: {'slot': {'id': 4433735760, 'this should only be in 3': []}}}

Возможным исправлением будет создание нового dict каждый раз, когда вам это нужно:

from pprint import pprint
test_dict = {}
for k in range(5):
    test_dict[k] = {}
    new = {'slot': dict()}
    new['slot']['id'] = id(new['slot'])
    test_dict[k].update(new)
    if k == 3:
        test_dict[k]['slot']['this should only be in 3'] = []
pprint(test_dict)

Вывод

{0: {'slot': {'id': 4399711968}},
 1: {'slot': {'id': 4399712528}},
 2: {'slot': {'id': 4399713088}},
 3: {'slot': {'id': 4399713648, 'this should only be in 3': []}},
 4: {'slot': {'id': 4399730768}}}
0 голосов
/ 17 февраля 2020

Метод update не создает копию new['slot'] для каждой записи в test_dict.

После

test_dict = {}
new = {}
new['slot'] = {}
for k in range(5):
    test_dict[k] = {}
    test_dict[k].update(new)
    if k == 3:
        test_dict[k]['slot']['this should only be in 3'] = []

test_dict[k]['slot'] является ссылкой на ту же самую dict для каждого k = 0, 1, ..., 4. Вы можете подтвердить это с помощью id:

>>> for k in range(5): id(test_dict[k]['slot'])
...
4422633104
4422633104
4422633104
4422633104
4422633104
>>> id(new['slot'])
4422633104
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...