Некорректно работает код при создании словаря через цикл

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

data_dict = {'10.180.12.49': {'printer_name': '',
                     'manufacture': '',
                     'cartridge_name': '',
                     'toner': 0,
                     'cartridges': 0,
                     'printed_pages': 0,
                     'date': []
                     },
    '10.180.102.23': {'printer_name': '',
                     'manufacture': '',
                     'cartridge_name': '',
                     'toner': 0,
                     'cartridges': 0,
                     'printed_pages': 0,
                     'date': []},
    '10.180.31.250': {'printer_name': '',
                     'manufacture': '',
                     'cartridge_name': '',
                     'toner': 0,
                     'cartridges': 0,
                     'printed_pages': 0,
                     'date': []}}
printer_ip = ['10.180.12.49', '10.180.102.23', '10.180.31.250']
manufacture = ['1', '2', '3']
cartridges = ['10', '15', '20']
for i in range(len(manufacture)):
    data_dict[printer_ip[i]]['manufacture'] = manufacture[i]
for i in range(len(cartridges)):
    data_dict[printer_ip[i]]['cartridges'] = cartridges[i]

А при создании точно такого же словаря с помощью цикла, он добавляет ко всем ключам только последние значения списков:

manufacture = ['1', '2', '3']
cartridges = ['10', '15', '20']
printer_ip = ['10.180.12.49', '10.180.102.23', '10.180.31.250']
data_dict = dict(zip(printer_ip, [{}]*len(printer_ip)))
r = {'printer_name': '',
     'manufacture': '',
     'cartridge_name': '',
     'toner': 0,
     'cartridges': 0,
     'printed_pages': 0,
     'date': []}
for i in range(len(printer_ip)):
    data_dict[printer_ip[i]].update(r)
for i in range(len(manufacture)):
    data_dict[printer_ip[i]]['manufacture'] = manufacture[i]
for i in range(len(cartridges)):
    data_dict[printer_ip[i]]['cartridges'] = cartridges[i]

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


Ответы (1 шт):

Автор решения: CrazyElf

Этот вопрос и подобные ему тут много раз обсуждался.

data_dict = dict(zip(printer_ip, [{}]*len(printer_ip)))
                                 ^^^^

Так вы размножаете один и тот же пустой словарь. А нужно создавать каждый раз новый пустой словарь:

data_dict = dict(zip(printer_ip, [{} for _ in range(len(printer_ip))])

А ещё лучше использовать defaultdict:

from collections import defaultdict

data_dict = defaultdict(dict)
→ Ссылка