не могу обновить defaultdict в методе строкового формата - PullRequest
0 голосов
/ 24 октября 2018

Я пытаюсь создать случайный цвет для каждого имени пользователя.

Когда я писал этот код, name1 и name2 имели одинаковый цвет.Что здесь не так?

import random
from collections import defaultdict

def get_color():
    print('call')
    return ''.join([random.choice('0123456789ABCDEF') for j in range(6)])

colors = defaultdict(get_color)

msg1 = {'name' : 'name1'}
msg2 = {'name' : 'name2'}

for msg in [msg1, msg2]:
    msg = '{colors[name]} {name}'.format(colors=colors, **msg)
    print(msg)

Вывод:

вызов

72C44D name1

72C44D name2

Спасибо

Ответы [ 3 ]

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

Печать colors после завершения цикла покажет вам

defaultdict(<function get_color at 0x7f6e7faed1e0>, {'name': '67C80A'})

, т.е. color имеет только одну клавишу.Вы получаете доступ к colors['name'] с жестко закодированным ключом 'name', а не colors[name] с динамическим именем.

Вам нужен еще один шаг форматирования.Один для создания шаблона, другой для вставки colors[name] в шаблон.

import random
from collections import defaultdict

def get_color():
    print('call')
    return ''.join([random.choice('0123456789ABCDEF') for j in range(6)])

colors = defaultdict(get_color)

msg1 = {'name' : 'name1'}
msg2 = {'name' : 'name2'}

for msg in [msg1, msg2]:
    msg_template = '{{colors[{name}]}} {{name}}'.format(**msg)
    print(msg_template) # for demo purposes
    msg = msg_template.format(colors=colors, **msg)
    print(msg)

Вывод

{colors[name1]} {name}
call
A70B47 name1
{colors[name2]} {name}
call
55709A name2
0 голосов
/ 24 октября 2018

Я отделил генерацию от печати, чтобы ее было легче читать.Вы можете упростить свой код, и это будет намного проще.

import random
from collections import defaultdict

def generate_color():
    color = ''.join([random.choice('0123456789ABCDEF') for j in range(6)])
    print ('generate_color returns', color)
    return color

colors = defaultdict(generate_color)

# simplify this. It's just a list of names
names = ['name1', 'name2']

# to call generate_color once for each name, 
# all you need to do is access that name in the default dict
print ('building colors')
for name in names:
    colors[name]

# now you have populated colors.
print ('printing colors')
for key in colors:
    # I went with simplifying the format string
    print ('{} {}'.format(key, colors[key]))
0 голосов
/ 24 октября 2018

Вы звоните get_colors() только один раз и назначаете сохраненный цвет (в colors) обоим сообщениям.Выполните следующие действия, чтобы сгенерировать случайный цвет для каждой итерации:

for msg in [msg1, msg2]:
    msg = '{colors[name]} {name}'.format(colors=defaultdict(get_color), **msg)
    print(msg)
...