简体   繁体   中英

Dictionary of lists to nested dictionary

I have the following dictionary {44: [0, 1, 0, 3, 6]} and need to convert this to dict1 = {44: {0:0, 1:1, 2:0, 3:3, 4:6}} but my current for loop doesn't work:

maxnumbers = 5          #this is how many values are within the list
for i in list(range(maxnumbers)):
    for k in list(dict1.keys()):
        for g in dict1[k]:
            newdict[i] = g
print(num4)

Can you help me? Thanks in advance.

You can use a dictionary comprehension with enumerate :

d = {44: [0, 1, 0, 3, 6]}

{k:dict(enumerate(v)) for k,v in d.items()}
# {44: {0: 0, 1: 1, 2: 0, 3: 3, 4: 6}}

Use a simple nested dictionary-comprehension that uses enumerate :

d = {44: [0, 1, 0, 3, 6]}

print({k: {i: x for i, x in enumerate(v)} for k, v in d.items()})
# {44: {0: 0, 1: 1, 2: 0, 3: 3, 4: 6}}
a = {44: [0, 1, 0, 3, 6]}
a= {i:{j:a[i][j] for i in a for j in range(len(a[i]))}}

print(a)

output

 {44: {0: 0, 1: 1, 2: 0, 3: 3, 4: 6}}

Why your current implementation doesn't work:

for i in list(range(maxnumbers)):
    for k in list(dict1.keys()):
        for g in dict1[k]:
            # this will iterate over all of the values in
            # d1[k] and the i: v pair will be overwritten by
            # the last value
            newdict[i] = g

Taken in steps, this would look like:

# for value in [0, 1, 0, 3, 6]: Just take this set of values as an example

# first, value is 0, and say we are on i = 1, in the outer for loop
newdict[1] = 0

# Then it will progress to value = 1, but i has not changed
# which overwrites the previous value
newdict[1] = 1

# continues until that set of values is complete

In order to fix this, you'll want i and the values of dict1[k] to increment together. This can be accomplished with zip :

for index, value in zip(range(maxnumbers), dict1[k]):
    newdict[index] = value

Also, if you need access to both the keys and values, use dict.items() :

for k, values in dict1.items():
    # then you can use zip on the values
    for idx, value in zip(range(maxnumbers), values):

However, the enumerate function already facilitates this:

for k, values in dict1.items():
    for idx, value in enumerate(values):
        # rest of loop

This is more robust, since you don't have to find what maxnumbers is ahead of time.

To do this in the traditional for loop that you've been using:

new_dict = {}

for k, v in dict1.items():
    sub_d = {} # create a new sub_dictionary
    for i, x in enumerate(v):
        sub_d[i] = x
    # assign that new sub_d as an element in new_dict
    # when the inner for loop completes
    new_dict[k] = sub_d

Or, more compactly:

d = {44: [0, 1, 0, 3, 6]}
new_d = {}

for k, v in d.items():
   new_d[k] = dict(enumerate(v))

Where the dict constructor will take an iterable of 2-element tuples as an argument, which enumerate provides

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