dict () в для цикла - другое поведение - PullRequest
0 голосов
/ 04 октября 2018

Я пытаюсь динамически обновлять значения для ключа dict() с помощью цикла for.

def update_dict():
    f = []
    for i, j in enumerate(list_range):
        test_dict.update({'a': i})
        j['c'] = test_dict
        print(j)
        f.append(j)
    print(f)

test_dict = dict({'a': 1})
list_range = [{'b': i} for i in range(0, 5)]
update_dict()

Даже print(j) дает итеративное значение (0,1,2,3,4), так или иначе последний дикт переписывается по всему списку и выдает неправильный вывод (4,4,4,4,4).

Ожидаемый вывод,

[{'b': 0, 'c': {'a': 0}}, {'b': 1, 'c': {'a': 1}}, {'b': 2, 'c': {'a': 2}}, {'b': 3, 'c': {'a': 3}}, {'b': 4, 'c': {'a': 4}}]

Полученный вывод,

[{'b': 0, 'c': {'a': 4}}, {'b': 1, 'c': {'a': 4}}, {'b': 2, 'c': {'a': 4}}, {'b': 3, 'c': {'a': 4}}, {'b': 4, 'c': {'a': 4}}]

Мне нужно понять, как словари перезаписываются и что может быть лучшим решением, чтобы избежать этого?

Заранее спасибо!

PS: пожалуйста, избегайте предлагать метод списка или диктов в качестве простого ответа, поскольку я знаю о них, и единственная цель этого вопроса - понять неправильное поведениеDICT ().

Ответы [ 4 ]

0 голосов
/ 04 октября 2018

Более простым решением может быть итерация по list_range и создание c с использованием значений из b

lista = [{'b': i } for i in range(0, 5)]
for i in lista:
    i['c'] = {'a': i['b']}
# [{'b': 0, 'c': {'a': 0}}, {'b': 1, 'c': {'a': 1}}, {'b': 2, 'c': {'a': 2}}, {'b': 3, 'c': {'a': 3}}, {'b': 4, 'c': {'a': 4}}]
0 голосов
/ 04 октября 2018
def update_dict():
   f = []
   for i, j in enumerate(list_range):
        j['c'] = {'a': i}
        print(j)
        f.append(j)
   return f

list_range = [{'b': i} for i in range(0, 5)]
print(update_dict())

#output
{'b': 0, 'c': {'a': 0}}
{'b': 1, 'c': {'a': 1}}
{'b': 2, 'c': {'a': 2}}
{'b': 3, 'c': {'a': 3}}
{'b': 4, 'c': {'a': 4}}
0 голосов
/ 04 октября 2018

Причина такого поведения заключается в том, что все ссылки в списке указывают на один и тот же аргумент.Строка j['c'] = test_dict не создает копию словаря, а просто заставляет j ['c'] обращаться к test_dict.Чтобы получить ожидаемый результат, вам нужно изменить эту строку на: j['c'] = test_dict.copy().Он сделает глубокую копию test_dict и назначит его j ['c'].

0 голосов
/ 04 октября 2018

Вы пытаетесь добавлять значения в один и тот же словарь каждый раз в цикле, и по мере продвижения цикла вы продолжаете заменять значения.

Вам необходимо определить словарь на каждой итерации, чтобы создать отдельный ссылки на словарь:

def update_dict():
    f = []
    for i, j in enumerate(list_range):
        test_dict = {'a': i}
        j['c'] = test_dict
        f.append(j)
    print(f)


list_range = [{'b': i} for i in range(0, 5)]
update_dict()

# [{'b': 0, 'c': {'a': 0}}, 
#  {'b': 1, 'c': {'a': 1}},
#  {'b': 2, 'c': {'a': 2}},
#  {'b': 3, 'c': {'a': 3}},
#  {'b': 4, 'c': {'a': 4}}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...