Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a dict of dicts

I have a several dictionaries containing the details of books where each entry corresponds to a different book.

books = [1,2]
titles = {1 : 'sum_title', 2: 'other_title'}
authors = {1 : 'sum_author', 2 : 'other_author'}
length = {1 : 100, 2 : 200}
chapters = { 1 : 10, 2: 20}

I would like to iterate through all of the books and combine the dictionaries into a single dict for turning into a .json. Here is what I have:

for book in (books):
    All_data.append({"authors": authors[book], "title": titles[book], "length": length[book]})

However this is returning a KeyError.

The reason I put the data into multiple dictionaries in the first place was so I could print and manipulate them seperately. For example; print all the authors, but not the titles. Is their a way I can combine the dictionaries into another dictionary and print the value of a key of a key such as print the author of book 1?

Thanks so much for the help. May your code be pretty and error-free.

like image 1000
Linux Lover Avatar asked May 21 '18 22:05

Linux Lover


Video Answer


2 Answers

You can use a list comprehension to create your new data structure:

data = [{'author': authors[b], 'title': titles[b], 'length': length[b]} for b in books]

>>> [{'author': 'sum_author', 'title': 'sum_title', 'length': 100}, {'author': 'other_author', 'title': 'other_title', 'length': 200}]

Or a dict comprehension for a "dict of dicts":

data = {b: {'author': authors[b], 'title': titles[b], 'length': length[b]} for b in books}

>>> {1: {'author': 'sum_author', 'title': 'sum_title', 'length': 100}, 2: {'author': 'other_author', 'title': 'other_title', 'length': 200}}
like image 58
bphi Avatar answered Sep 22 '22 08:09

bphi


You may find a functional approach more adaptable. This is not necessarily more efficient than writing keys explicitly in your dictionary comprehension, but it is more easily extendable:

from operator import itemgetter

keys = ['titles', 'authors', 'length', 'chapters']
values = [titles, authors, length, chapters]

res = [{i: itemgetter(book)(j) for i, j in zip(keys, values)} for book in books]

[{'authors': 'sum_author',
  'chapters': 10,
  'length': 100,
  'titles': 'sum_title'},
 {'authors': 'other_author',
  'chapters': 20,
  'length': 200,
  'titles': 'other_title'}]
like image 35
jpp Avatar answered Sep 21 '22 08:09

jpp