Reputation: 3048
I have a dict
which looks something like
A = {
'test1':{'q0':[0.123,0.234],'phi0':[0.124,0.4325],'m':[9.42,0.3413]},
'test2':{'q0':[0.343,0.353],'phi0':[0.2341,0.235]},
'test3':{'q0':[0.343,0.353],'phi0':[0.2341,0.235],'m':[0.325,0.325],'z0':[0.234,0.314]}
}
I want to print each individual dictionary:
'test1': q0=0.123(0.234) phi0=0.123(0.4325) m=9.42(0.3413)
'test2': q0=0.343(0.353) phi0=0.2341(0.235)
'test3': z0=0.234(0.314) q0=0.343(0.353) phi0=0.2341(0.235) m=0.325(0.325)
How to do so in Python 3 using thestring.format()
? Since each sub-dictionary has variable number of 'parameters', I am not sure how to accomplish it using some list/dictionary comprehension. Also, if I want to leave some space if that parameter is missing like what is shown, how do I do it? Each dictionary has at most five different parameters (q0,phi0,m,c,z0). I juts print it to the terminal so I don't need something very fancy, but I hope it can be more readible.
Upvotes: 1
Views: 1528
Reputation: 1539
Try this:-
A = {
'test1':{'q0':[0.123,0.234],'phi0':[0.124,0.4325],'m':[9.42,0.3413]},
'test2':{'q0':[0.343,0.353],'phi0':[0.2341,0.235]},
'test3':{'q0':[0.343,0.353],'phi0':[0.2341,0.235],'m':[0.325,0.325],'z0':[0.234,0.314]}
}
for i,j in A.items():
print i+':',
for x,y in j.items():
print "{}= {}({})".format(x,y[0],y[1]),
print
#output is same as expected
Upvotes: 0
Reputation: 46789
As both your tests and parameters are in dictionaries, you could first sort them to ensure a consistent ordering. Simple sorting may not work though as if you had test13
, by default in would appear after test1
. You could use the Python library natsort
to help with this.
As each set of parameters could have missing values, a quick search could be used to create a list of all of the cols
that are needed. You could then reserve space when printing for rows with missing values:
from natsort import natsorted
A = {
'test1':{'q0':[0.123,0.234],'phi0':[0.124,0.4325],'m':[9.42,0.3413]},
'test2':{'q0':[0.343,0.353],'phi0':[0.2341,0.235]},
'test3':{'q0':[0.343,0.353],'phi0':[0.2341,0.235],'m':[0.325,0.325],'z0':[0.234,0.314]},
'test13':{'q0':[0.343,0.353],'z0':[0.234,0.314]}
}
sorted_tests = natsorted(A.items()) # Ensure test13 is numerical sorted correctly
# Create a list of all required cols
cols = set()
for test, params in sorted_tests:
cols.update(params.keys())
cols = sorted(cols)
for test, params in sorted_tests:
row = [(col, params.get(col, [])) for col in cols]
cells = []
for p, values in row:
if values:
cells.append('{:20}'.format('{}={}({})'.format(p, values[0], values[1])))
else:
cells.append('{:20}'.format(''))
print("{:6} : {}".format('{}'.format(test), ''.join(cells)))
This would give you the following output:
test1 : m=9.42(0.3413) phi0=0.124(0.4325) q0=0.123(0.234)
test2 : phi0=0.2341(0.235) q0=0.343(0.353)
test3 : m=0.325(0.325) phi0=0.2341(0.235) q0=0.343(0.353) z0=0.234(0.314)
test13 : q0=0.343(0.353) z0=0.234(0.314)
Upvotes: 1
Reputation: 4543
use a nested loop:
for m,x in A.items():
for y,z in x.items():
print(m,'{0}='.format(y), z[0],'({0})'.format(z[1]))
Upvotes: 1
Reputation: 24623
Try following code based on for
loop which produces a sorted output:
outlist = []
for a in A:
outstr = a+":"
for aa in ('z0', 'q0','phi0','m','c'):
if aa in A[a]:
outstr += aa+"="+str(A[a][aa][0])+"("+str(A[a][aa][1])+") "
else:
outstr += " "
outlist.append(outstr)
for i in sorted(outlist):
print(i)
Output:
test1: q0=0.123(0.234) phi0=0.124(0.4325) m=9.42(0.3413)
test2: q0=0.343(0.353) phi0=0.2341(0.235)
test3:z0=0.234(0.314) q0=0.343(0.353) phi0=0.2341(0.235) m=0.325(0.325)
Upvotes: 0
Reputation: 5109
Check if 'z0'
is in the keys of the sub-dictionaries, and to those items, apply a slightly different string operation than the ones that don't have that key. Looks a little dirty but produces your output exactly:
for k,v in A.items():
if 'z0' in v:
print (k,":","{}={}({})".format('z0',v['z0'][0],v['z0'][1]), " ".join("{}={}({})".format(e,t[0],t[1]) for e,t in v.items() if 'z0' not in e))
else:
print (k,": "," ".join("{}={}({})".format(e,t[0],t[1]) for e,t in v.items()))
Result:
test1 : q0=0.123(0.234) phi0=0.124(0.4325) m=9.42(0.3413)
test2 : q0=0.343(0.353) phi0=0.2341(0.235)
test3 : z0=0.234(0.314) q0=0.343(0.353) phi0=0.2341(0.235) m=0.325(0.325)
Note: If you really need those single quotes around the test
s, i.e. 'test1'
instead of test1
, you can add "'"
to the left and right of k
in the two print
statements of mine: print ("'",k,"'",...
Upvotes: 1
Reputation: 107347
Note that dictionaries are unordered data structures, hence you can't expect any order in printing the items unless you use their ordered equivalent collections.OrderedDict()
. Nevertheless, you can use a generator expression within str.join()
method :
In [4]: for key, value in A.items():
print(','.join(("{}: {}={}({})".format(key, t1,t2,t3) for t1, (t2, t3) in value.items())))
...:
test1: q0=0.123(0.234),test1: phi0=0.124(0.4325),test1: m=9.42(0.3413)
test3: q0=0.343(0.353),test3: phi0=0.2341(0.235),test3: m=0.325(0.325),test3: z0=0.234(0.314)
test2: q0=0.343(0.353),test2: phi0=0.2341(0.235)
Also note that since we're doing the following inline unpacking it may raise a ValueError if number of the items in lists is more/less than two.
for t1, (t2, t3) in value.items()
Therefore, make sure that the number of unpacking variables match with the number of items in list.
Upvotes: 5