Home > Net >  Printing numbers in a dictionary inside a dictionary by python
Printing numbers in a dictionary inside a dictionary by python

Time:05-19

I want to print numbers in a dictionary inside a dictionary :

frame = ['frame1', 'frame2', 'frame3', 'frame4', 'frame5', 'frame6']
dx = [12, 34, 55, 66, 78, 65, 56, 234, 876, 999, 345, 945]
pd = ['pd1', 'pd2']

data = {}
dt = {}
k=0
for i in pd :
    dt[i] = []
    for j in frame :
        data[j] = dt
        data[j][i] = dx[k]
        k =1

For this code it only passes the last values :

{'frame1': {'pd1': 65, 'pd2': 945}, 'frame2': {'pd1': 65, 'pd2': 945}, 'frame3': {'pd1': 65, 'pd2': 945}, 'frame4': {'pd1': 65, 'pd2': 945}, 'frame5': {'pd1': 65, 'pd2': 945}, 'frame6': {'pd1': 65, 'pd2': 945}}

This is the result I want:

{'frame1': {'pd1': 12, 'pd2': 56}, 'frame2': {'pd1': 34, 'pd2': 234}, 'frame3': {'pd1': 55, 'pd2': 876}, 'frame4': {'pd1': 66, 'pd2': 999}, 'frame5': {'pd1': 78, 'pd2': 345}, 'frame6': {'pd1': 65, 'pd2': 945}}

CodePudding user response:

It looks like there's some shared memory across all the dictionaries.

You can construct the dictionary using a dictionary comprehension:

{f: dict(zip(pd, vals)) for f, vals in zip(frame, zip(dx[:len(dx)//2], dx[len(dx)//2:]))}

This outputs:

{
 'frame1': {'pd1': 12, 'pd2': 56}, 'frame2': {'pd1': 34, 'pd2': 234}, 
 'frame3': {'pd1': 55, 'pd2': 876}, 'frame4': {'pd1': 66, 'pd2': 999}, 
 'frame5': {'pd1': 78, 'pd2': 345}, 'frame6': {'pd1': 65, 'pd2': 945}
}

CodePudding user response:

You can get it from a nested dictionary comperhension, but it is a bit long:

{f: d for f, d in zip(frame, {pd[0]: i, pd[1]: j} for i, j in zip(dx[:len(frame)], dx[len(frame):]))}

A little simplification:

dict(zip(frame, (dict(zip(pd, x)) for x in zip(dx[:len(frame)], dx[len(frame):]))))

Output:

{'frame1': {'pd1': 12, 'pd2': 56},
 'frame2': {'pd1': 34, 'pd2': 234},
 'frame3': {'pd1': 55, 'pd2': 876},
 'frame4': {'pd1': 66, 'pd2': 999},
 'frame5': {'pd1': 78, 'pd2': 345},
 'frame6': {'pd1': 65, 'pd2': 945}}

CodePudding user response:

This should work

data = {}
k=0
for i in pd:
    for j in frame :
        # use setdefault to initialize inner dictionary
        data.setdefault(j, {})[i] = dx[k]
        k =1
data
{'frame1': {'pd1': 12, 'pd2': 56},
 'frame2': {'pd1': 34, 'pd2': 234},
 'frame3': {'pd1': 55, 'pd2': 876},
 'frame4': {'pd1': 66, 'pd2': 999},
 'frame5': {'pd1': 78, 'pd2': 345},
 'frame6': {'pd1': 65, 'pd2': 945}}

CodePudding user response:

Your issue is that you're resetting dt over every iteration of your outer for-loop. To get your desired output, just do this

for i in pd:
    for j in frame:
        if j not in data:
            data[j] = dict()
        data[j][i] = dx[k]
        k  = 1

You can compress this into a list comprehension like this:

data = {f: {p: dx[j * len(frame)   i] for j, p in enumerate(pd)} for i, f in enumerate(frame)}

This compression iterates over frames and, for each item in frames, iterates over pd. For each item in pd, we then add items to a dictionary when we then add to the larger dictionary. The value of dx added to the dictionary is based on the jth entry of pd and the ith entry of frames.

CodePudding user response:

Better variable names help track what is going on. Readability counts vs. one-liner list comprehensions. The original code was inserting the same modified dictionary in each frame.

from pprint import pprint

frames = ['frame1', 'frame2', 'frame3', 'frame4', 'frame5', 'frame6']
dx = [12, 34, 55, 66, 78, 65, 56, 234, 876, 999, 345, 945]
pds = ['pd1', 'pd2']

# Initialize each frame with a *different* empty dictionary
data = {frame:{} for frame in frames}

# Distribute dx across the frames and pds:
k = iter(dx)
for pd in pds:
    for frame in frames:
        data[frame][pd] = next(k)

pprint(data)

Output:

{'frame1': {'pd1': 12, 'pd2': 56},
 'frame2': {'pd1': 34, 'pd2': 234},
 'frame3': {'pd1': 55, 'pd2': 876},
 'frame4': {'pd1': 66, 'pd2': 999},
 'frame5': {'pd1': 78, 'pd2': 345},
 'frame6': {'pd1': 65, 'pd2': 945}}
  • Related