I am trying to print my nested dictionary in a table format. But have not been able to do so. The table is a list of student names and student grades. I would like it to be in a "Report Card" type format that is easy to read. The for loop I am using prints out the results. But it is one column list form.
This is my current dictionary I have setup.
student = {
"student1": {
"Name": "Eddy",
"Grade": 1,
"Math": 78,
"English": 65,
"Physics": 89,
"Chemistry": 80
},
"student2": {
"Name": "Jim",
"Grade": 2,
"Math": 89,
"English": 65,
"Physics": 87,
"Chemistry": 76
},
"student3": {
"Name": "Jane",
"Grade": 3,
"Math": 87,
"English": 97,
"Physics": 75,
"Chemistry": 64
},
}
This is the for loop I am currently using.
for i in student:
for j in student[i]:
print(j + " : " + str(student[i][j]))
print("===========")
I would like to print out in a table format.
Name Grade Math English Physics Chemistry
Eddy 1 78 65 89 80
Jim 2 89 65 87 76
Jane 3 87 97 75 64
I have tried to use the format()
function but could not make it work with the nested dictionary.
I also tried using pandas
and converting to a pd.DataFrame
, but could not make it work.
First: print()
as default add new line
at the end so if you want to display in one line then you have to use print(..., end="")
I think you should learn string formatting
- see page pyFormat.info. This way you can better control elements in row then using spaces or \t
.
It needs to work with all elements at once instead of using internal for
-loop but this gives better control and needs simpler code.
for stud, val in student.items():
print("{:4} {:^5} {:^4} {:^7} {:^7} {:^9}".format(val["Name"], val["Grade"], val["Math"], val["English"], val["Physics"], val["Chemistry"]))
I use items()
to get all values for one studen and later use val["Name"]
, val["Grade"}
, etc. so I'm sure I put values in correct order.
I use {}
to define where to put element in string, and using {:^5}
I define that it should use field which has 5 chars (it will add spaces if text is shorter) and ^
means it should center value in this field.
Name Grade Math English Physics Chemistry
Eddy 1 78 65 89 80
Jim 2 89 65 87 76
Jane 3 87 97 75 64
In string formatting
you can use {}
with any other text to decoreate table. For example you can put |
between fields to create
+------+-------+------+---------+---------+-----------+
| Name | Grade | Math | English | Physics | Chemistry |
+------+-------+------+---------+---------+-----------+
| Eddy | 1 | 78 | 65 | 89 | 80 |
| Jim | 2 | 89 | 65 | 87 | 76 |
| Jane | 3 | 87 | 97 | 75 | 64 |
+------+-------+------+---------+---------+-----------+
student = {
"student1": {
"Name": "Eddy",
"Grade": 1,
"Math": 78,
"English": 65,
"Physics": 89,
"Chemistry": 80
},
"student2": {
"Name": "Jim",
"Grade": 2,
"Math": 89,
"English": 65,
"Physics": 87,
"Chemistry": 76
},
"student3": {
"Name": "Jane",
"Grade": 3,
"Math": 87,
"English": 97,
"Physics": 75,
"Chemistry": 64
},
}
print('Name Grade Math English Physics Chemistry')
for stud, val in student.items():
print("{:4} {:^5} {:^4} {:^7} {:^7} {:^9}".format(val["Name"], val["Grade"], val["Math"], val["English"], val["Physics"], val["Chemistry"]))
print('+------+-------+------+---------+---------+-----------+')
print('| Name | Grade | Math | English | Physics | Chemistry |')
print('+------+-------+------+---------+---------+-----------+')
for stud, val in student.items():
print("| {:4} | {:^5} | {:^4} | {:^7} | {:^7} | {:^9} |".format(val["Name"], val["Grade"], val["Math"], val["English"], val["Physics"], val["Chemistry"]))
print('+------+-------+------+---------+---------+-----------+')
BTW: to make it more universal you could use list 'Name', 'Grade', 'Math', 'English', 'Physics', 'Chemistry']
to decide which values display. You could also need code which calculate width for columns but it would be more complex code.
Here is a pandas solution, as you mentioned unsuccessfully trying pandas. You can use pandas.DataFrame.from_dict
with orient=index
.
import pandas as pd
df = pd.DataFrame.from_dict(student, orient='index').reset_index(drop=True)
You get
Name Grade Math English Physics Chemistry
0 Eddy 1 78 65 89 80
1 Jim 2 89 65 87 76
2 Jane 3 87 97 75 64
markdown
tablepandas.DataFrame.to_markdown()
print(df.to_markdown(index=False))
| Name | Grade | Math | English | Physics | Chemistry |
|:-------|--------:|-------:|----------:|----------:|------------:|
| Eddy | 1 | 78 | 65 | 89 | 80 |
| Jim | 2 | 89 | 65 | 87 | 76 |
| Jane | 3 | 87 | 97 | 75 | 64 |
import matplotlib.pyplot as plt
df.plot.barh(x='Name', y=['Math', 'English', 'Physics', 'Chemistry'], figsize=(6, 8))
plt.xlabel('Score')
plt.legend(title='Subject', bbox_to_anchor=(1.05, 1), loc='upper left')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With