Перебор значений словаря, которые являются списками, для создания нового списка словарей - PullRequest
2 голосов
/ 06 марта 2019

У меня есть словарь с ключами «Заголовок», «Автор», «Год публикации», со значениями, которые являются списками:

book_dict= {'Titles': ['Double Play', 'Slow Burn', 'Altman Code'], 'Authors': ['Brown, Dan', 'Hannah, Kristin', 'Neri, Penelope'], 
'Publication Year': [2004, 2003, 2006]}

Позиции каждой записи в списке соответствуют друг другу,такие, что book_dict['Titles'][0] и book_dict['Authors'][0] являются информацией об одной и той же книге.(примечание: это настоящие имена книг и авторов, но на самом деле они не соответствуют друг другу)

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

[{"Title":"Double Play","Author":"Brown, Dan", "Publication Year":2004}, 
{"Title":"Slow Burn","Author":"Hannah, Kristin", "Publication Year":2003},
{"Title":"Altman Code","Author":"Neri, Penelope'", "Publication Year":2006}]

ИтакПока я пробовал это:

for i in range(30):
    for k,v in book_dict.items():
        print({k[i]:v[i]})

Но я получаю это вместо:

{"Title":"Double Play"}
{"Author":"Brown, Dan"}
{"Publication Year":2004}
{"Title":"Slow Burn"}
{"Author":"Hannah, Kristin"}
{"Publication Year":2003}
{"Title":"Altman Code"}
{"Author":"Neri, Penelope"} 
{"Publication Year":2006}

Плюс IndexError: list index out of range

Ответы [ 4 ]

3 голосов
/ 06 марта 2019

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

[dict(zip(book_dict, t)) for t in zip(*book_dict.values())]

Возвращает:

[{'Titles': 'Double Play', 'Authors': 'Brown, Dan', 'Publication Year': 2004},
 {'Titles': 'Slow Burn', 'Authors': 'Hannah, Kristin', 'Publication Year': 2003},
 {'Titles': 'Altman Code', 'Authors': 'Neri, Penelope', 'Publication Year': 2006}]
3 голосов
/ 06 марта 2019

Вам нужно будет использовать какой-то вариант zip для значений исходного диктанта:

>>> [{'Title': t, 'Author': a, 'Publication Year': y} for t, a, y in zip(book_dict['Titles'], book_dict['Authors'], book_dict['Publication Year'])]
[{'Title': 'Double Play', 'Author': 'Brown, Dan', 'Publication Year': 2004}, 
 {'Title': 'Slow Burn', 'Author': 'Hannah, Kristin', 'Publication Year': 2003}, 
 {'Title': 'Altman Code', 'Author': 'Neri, Penelope', 'P
ublication Year': 2006}]

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

from  operator import itemgetter

items = itemgetter('Titles', 'Authors', 'Publication Year')
[
    {'Title': t, 'Author': a, 'Publication Year': y} 
    for t, a, y in zip(*items(book_dict))
]
# [{'Title': 'Double Play', 'Author': 'Brown, Dan', 'Publication Year': 2004}, 
#  {'Title': 'Slow Burn', 'Author': 'Hannah, Kristin', 'Publication Year': 2003}, 
#  {'Title': 'Altman Code', 'Author': 'Neri, Penelope', 'Publication Year': 2006}]
1 голос
/ 06 марта 2019

Вы можете использовать zip() для итерации по нескольким спискам на шаге, например, в

result = []
for title, author, year in zip(book_dict['Titles'], book_dict['Authors'],     
book_dict['Publication Year']):
    result.append({'Title': title, 'Author': author, 'Year': year})

print result
1 голос
/ 06 марта 2019

Попробуйте это:

[{k : book_dict[k][j] for k in book_dict} for j in range(len(book_dict['Titles']))]

ВЫХОД :

[{'Titles': 'Double Play', 'Authors': 'Brown, Dan', 'Publication Year': 2004}, {'Titles': 'Slow Burn', 'Authors': 'Hannah, Kristin', 'Publication Year': 2003}, {'Titles': 'Altman Code', 'Authors': 'Neri, Penelope', 'Publication Year': 2006}]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...