Создание dict, содержащего sub-dict в качестве нового значения с индексом в качестве ключа - PullRequest
0 голосов
/ 25 сентября 2018

У меня есть словарь, настроенный в настоящее время как

{'name': 'firm', 'name':'firm', etc}, 

Где ключи - это имена аналитиков, а значения - это фирмы-аналитики.

Я пытаюсь создать новый словарь, в котором новые значения являютсястарые пары k, v и связанный ключ - это просто индекс (1, 2, 3, 4, etc).

Текущий код ниже:

num_analysts = len(analysts.keys())
for k,v in analysts.items():
    analysts_dict = dict.fromkeys(range(num_analysts), [k,v])

Текущий результат

Каждый цифровой ключ получает одно и то же значение (old k,v pair).Что не так с моим выражением?

Ответы [ 5 ]

0 голосов
/ 25 сентября 2018

Этот код

for k,v in analysts.items(): 
    analysts_dict = dict.fromkeys(range(num_analysts), [k,v])

зацикливает исходный dict и на каждой итерации цикла создает новый dict, используя номера диапазона в качестве ключей.Кстати, каждый элемент в этом диктанте имеет ссылку на один объект списка [k, v].Это вообще плохая идея.Вы должны использовать только неизменяемый объект (например, None, число или строку) в качестве значения аргумента для метода dict.fromkeys.Цель метода - позволить вам создать dict с простым значением по умолчанию для ключей, которые вы предоставляете, вы не можете использовать его для создания dict со списками в качестве значений, если вы хотите, чтобы эти списки были отдельными списками.

Новый объект dict связан с именем analysts_dict.На следующей итерации цикла создается новый dict и привязывается к этому имени, заменяя тот, который только что был создан в предыдущем цикле, а замененный dict уничтожается.

Таким образом, вы получите analysts_dict, содержащийкуча ссылок на окончательную пару [k, v], прочитанную из исходного диктанта.

Чтобы получить желаемый результат, вы должны использовать код DYZ, который я не буду здесь повторять.Обратите внимание, что в кортежах хранится старое имя и информация о фирме, что лучше, чем использование списков для этого приложения.

0 голосов
/ 25 сентября 2018

Во время каждой итерации, analysts_dict присваивается значение на основе результата dict.items ().Тем не менее, вы должны использовать понимание для генерации окончательного результата в одну строку,

Например [{i: e} for i, e in enumerate(analysts.items())]

analysts = {
    "a": 13,
    "b": 123,
    "c": 1234
}
num_analysts = len(analysts.keys())
analysts_dict = [{i: e} for i, e in enumerate(analysts.items())]
print(analysts_dict)

>> [{0: ('a', 13)}, {1: ('b', 123)}, {2: ('c', 1234)}]
0 голосов
/ 25 сентября 2018

Перечислите и словарь для этого

d = {'name1': 'firm1', 'name2': 'firm2'}
d2 = {idx: '{}, {}'.format(item, d[item]) for idx, item in enumerate(d, start = 1)}
{1: 'name1, firm1', 2: 'name2, firm2'}
0 голосов
/ 25 сентября 2018

Уже есть эффективный ответ, опубликованный другими.Поэтому я могу просто указать причину, по которой ваше собственное решение не работает должным образом.Это может быть вызвано ленивой привязкой.Есть хороший ресурс по: http://quickinsights.io/python/python-closures-and-late-binding/

Поскольку поздняя привязка буквально выберет последнюю в созданном вами словаре.Но этот последний не «фактически последний», это определяется ОС.(Другие люди уже дают некоторые пояснения относительно структуры данных dict.)

При каждом запуске в командной строке python результат может меняться.Если вы поместите код в файл .py, то при каждом запуске в IDE результат будет одинаковым (всегда последний в dict)

0 голосов
/ 25 сентября 2018

Вы можете перечислять элементы и преобразовывать их в словарь.Однако словари, как правило, не упорядочены.Это означает, что ключи могут быть назначены в основном случайным образом.

dict(enumerate(analysts.items(), 1))
#{1: ('name1', 'firm1'), 2: ('name2', 'firm2')}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...