简体   繁体   中英

Parse list into dictionaries within a dictionary Python

dataset:

id = [1,2,3]
header = ['name','attack','defense']
stats = [['John',12,30], ['Amy',32,89], ['Lisa',45,21]]

I would like to obtain an output in the form of a nested dictionary. The keys of the outer dictionary will be the id and the values will be dictionaries the contain the other data. ie:

dict = {
    1: {'name': 'John', 'attack': 12, 'defense': 30}, 
    2: {'name': 'Amy', 'attack': 32, 'defense': 89},
    3: {'name': 'Lisa', 'attack': 45, 'defense': 21}
}

this is my current code:

dict = {}
for i in id:
    next_input = {}
    for index, h in enumerate (header):
        for sublist in stats:
            next_input[h] = sublist[index]
    dict[i] = next_input

It is not working because of the last for loop. the value of the inner dictionaries are just replacing themselves until the last sublist.

How can I correct this code?

You don't need to loop over the stats sublists; using the enumerate() option you picked, you'd have to add an index to the id loop and pick the right stats:

dict = {}
for id_index, i in enumerate(id):
    next_input = {}
    for h in enumerate (header):
        next_input[h] = sublist[id_index][index]
    dict[i] = next_input

However, you can use the zip() function to pair up two lists for parallel iteration:

result = {i: dict(zip(header, stat)) for i, stat in zip(id, stats)}

This uses a dictionary comprehension to build the outer mapping from id value to corresponding stats entry. The inner dictionary is simply build from the paired headers and statistics ( dict() takes a sequence of (key, value) pairs).

Demo:

>>> id = [1,2,3]
>>> header = ['name','attack','defense']
>>> stats = [['John',12,30], ['Amy',32,89], ['Lisa',45,21]]
>>> {i: dict(zip(header, stat)) for i, stat in zip(id, stats)}
{1: {'attack': 12, 'defense': 30, 'name': 'John'}, 2: {'attack': 32, 'defense': 89, 'name': 'Amy'}, 3: {'attack': 45, 'defense': 21, 'name': 'Lisa'}}
>>> from pprint import pprint
>>> pprint(_)
{1: {'attack': 12, 'defense': 30, 'name': 'John'},
 2: {'attack': 32, 'defense': 89, 'name': 'Amy'},
 3: {'attack': 45, 'defense': 21, 'name': 'Lisa'}}

You can try this:

id = [1,2,3]
header = ['name','attack','defense']
stats = [['John',12,30], ['Amy',32,89], ['Lisa',45,21]]

new_dict = {a:{d:c for c, d in zip(b, header)} for a, b in zip(id, stats)}

Output:

{1: {'attack': 12, 'defense': 30, 'name': 'John'}, 2: {'attack': 32, 'defense': 89, 'name': 'Amy'}, 3: {'attack': 45, 'defense': 21, 'name': 'Lisa'}}

Another zip() variation:

d = {}
for i,s in enumerate(stats):
    d[id[i]] = dict((zip(header, s)))

print(d)

The output:

{1: {'attack': 12, 'name': 'John', 'defense': 30}, 2: {'attack': 32, 'name': 'Amy', 'defense': 89}, 3: {'attack': 45, 'name': 'Lisa', 'defense': 21}}

use zip() and list comphersion

>> dict(zip(id ,[dict(zip(header,item)) for item in stats]))

{1: {'attack': 12, 'defense': 30, 'name': 'John'}, 2: {'attack': 32, 'defense': 89, 'name': 'Amy'}, 3: {'attack': 45, 'defense': 21, 'name': 'Lisa'}}

first zip every item in stats with header

>>> [dict(zip(header,item)) for item in stats]

[{'attack': 12, 'defense': 30, 'name': 'John'}, {'attack': 32, 'defense': 89, 'name': 'Amy'}, {'attack': 45, 'defense': 21, 'name': 'Lisa'}]

second zip id with the output of first

>>> zip(id,[dict(zip(header,item)) for item in stats])

[(1, {'attack': 12, 'defense': 30, 'name': 'John'}), (2, {'attack': 32, 'defense': 89, 'name': 'Amy'}), (3, {'attack': 45, 'defense': 21, 'name': 'Lisa'})]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM