#python #list #dictionary #immutability
#python #Список #словарь #неизменяемость
Вопрос:
Я работаю на C , я новичок в Python, и я подозреваю, что эта проблема как-то связана с изменчивостью [im].
Я создаю представление JSON в Python, которое включает в себя несколько слоев вложенных списков и словарей в одном «объекте». Моя цель — вызвать jsonify
конечный результат и сделать его похожим на хорошо структурированные данные.
Я столкнулся с проблемой при создании объекта:
approval_groups_list = list()
approval_group_dict = dict()
for groupMemKey, groupvals in groupsAndMembersDict.items():
approval_group_dict["group_name"] = groupMemKey
approval_group_dict["name_dot_numbers"] = groupvals # groupvals is a list of strings
approval_groups_list.append(approval_group_dict)
entity_approval_unit["approval_groups"] = approval_groups_list
Первый запуск выполняется так, как ожидалось, но после того, какой бы groupMemkey ни был затронут последним, это то, что отражают все остальные объекты.
groupsAndMembersDict= {
'Art': ['string.1', 'string.2', 'string.3'],
'Math': ['string.10', 'string.20', 'string.30']
}
Ожидаемый результат:
approval_groups:
[
{
"group_name": "Art",
"name_dot_numbers": ['string.1', 'string.2', 'string.3']
},
{
"group_name": "Math",
"name_dot_numbers": ['string.10', 'string.20', 'string.30']
}
]
Фактический результат:
approval_groups:
[
{
"group_name": "Math",
"name_dot_numbers": ['string.10', 'string.20', 'string.30']
},
{
"group_name": "Math",
"name_dot_numbers": ['string.10', 'string.20', 'string.30']
}
]
Что происходит, и как мне это исправить?
Комментарии:
1.Потому что вы продолжаете назначать один и тот же список одному и тому же dict
approval_group_dict["name_dot_numbers"] = groupvals
и впоследствии добавляете его кapproval_groups_list
. Это не имеет ничего общего с изменчивостью / неизменяемостью. Проще говоря,approval_group_dict["name_dot_numbers"] = groupvals
не создает копиюgroupvals
иapproval_groups_list.append(approval_group_dict)
не создает копиюapproval_group_dict
Ответ №1:
Ваша проблема заключается не в неизменности, а в изменчивости объектов. Я уверен, что вы получили бы тот же результат с эквивалентным кодом C .
Вы создаете approval_group_dict
перед for
циклом и продолжаете использовать его повторно. Все, что вам нужно сделать, это переместить конструкцию внутрь for
, чтобы для каждого цикла создавался новый объект:
approval_groups_list = list()
for groupMemKey, groupvals in groupsAndMembersDict.items():
approval_group_dict = dict()
...
Ответ №2:
При написании этого вопроса мне пришло в голову попробовать несколько вещей, включая это, которые устранили мою проблему — однако я до сих пор точно не знаю, почему это работает. Возможно, это больше похоже на проблему с указателем / ссылкой?
approval_groups_list = list()
approval_group_dict = dict()
for groupMemKey, groupvals in groupsAndMembersDict.items():
approval_group_dict["group_name"] = groupMemKey
approval_group_dict["name_dot_numbers"] = groupvals
approval_groups_list.append(approval_group_dict.copy()) # <== note, here is the difference ".copy()"
entity_approval_unit["approval_groups"] = approval_groups_list
РЕДАКТИРОВАТЬ: Проблема заключается в том, что Python все время передается по ссылке [object]. Если вы новичок в Python, как и я, это означает: «передавайте по ссылке, за исключением случаев, когда передаваемая вами вещь неизменяема, тогда она передается по значению». Таким образом, в некотором смысле это действительно имело отношение к изменчивости [im]. В основном это было связано с моим непониманием того, как Python передает ссылки.
Комментарии:
1. В принципе, все в Python действует как ссылка, ничто никогда не копируется неявно.
2. да, это было оно.