Почему словарь ключ:список заполняется в цикле одним последним списком, хотя ключи и списки уникальные?
Надо создать словарь ключом в котором будет имя, а значением список строк, в котором присутствует это имя и индекс от 0 до 2:
{name : [url1+name+url2+0, url1+name+url2+1, url1+name+url2+2]}
Вот мой код:
def get_urls():
"""
Returns a dictionary with each element being:
{name : [url1+name+url2+0, url1+name+url2+1, url1+name+url2+2]}
"""
url1 = "string1-"
url2 = "-string2-"
temp_l = [''] * 3
names = ['alex', 'john', 'max', 'yen']
main_dict = {}
for name in names:
for i in range(3):
temp_l[i] = url1 + name + url2 + str(i)
main_dict[name] = temp_l
print(temp_l)
return main_dict
dic = get_urls()
for d in dic:
print(d, dic[d])
Если выводить список в каждой итерации цикла, получается:
['string1-alex-string2-0', 'string1-alex-string2-1', 'string1-alex-string2-2']
['string1-john-string2-0', 'string1-john-string2-1', 'string1-john-string2-2']
['string1-max-string2-0', 'string1-max-string2-1', 'string1-max-string2-2']
['string1-yen-string2-0', 'string1-yen-string2-1', 'string1-yen-string2-2']
Как и должно быть, но конечный словарь весь заполняется последним списком:
alex ['string1-yen-string2-0', 'string1-yen-string2-1', 'string1-yen-string2-2']
john ['string1-yen-string2-0', 'string1-yen-string2-1', 'string1-yen-string2-2']
max ['string1-yen-string2-0', 'string1-yen-string2-1', 'string1-yen-string2-2']
yen ['string1-yen-string2-0', 'string1-yen-string2-1', 'string1-yen-string2-2']
Так же пробовал через 'main_dict.update' - результат такой же. Значения всех ключей заполняются последним списком.
Ответы (2 шт):
Ключевая ошибка в этой строке (в теле цикла for name in names):
main_dict[name] = temp_l
Вы до этого выделили в памяти список, обозначили его temp_l.
Потом чему-то присвоили, а потом ссылку на него присвоили элементу словаря.
В следующей итерации вы изменили список... В этот момент уже что-то идет не так.
Элемент словаря из прошлой итерации тоже поменялся. А в конечном итоге, все элементы словаря смотрят на одну и ту же область памяти.
Решение:
Делать копию списка, например, так:
main_dict[name] = temp_l[:]
Или любым другим способом, который можно найти в поисковике.
я бы посоветовал следовать "Single-responsibility principle " при написании функций:
def get_record(name, url1, url2, n=3):
return [f"{url1}{name}{url2}{i}" for i in range(n)]
res = {name: get_record(name, url1, url2) for name in names}
результат:
In [291]: res
Out[291]:
{'alex': ['string1-alex-string2-0',
'string1-alex-string2-1',
'string1-alex-string2-2'],
'john': ['string1-john-string2-0',
'string1-john-string2-1',
'string1-john-string2-2'],
'max': ['string1-max-string2-0',
'string1-max-string2-1',
'string1-max-string2-2'],
'yen': ['string1-yen-string2-0',
'string1-yen-string2-1',
'string1-yen-string2-2']}