以表格形式打印嵌套字典

4

我想将嵌套字典以表格形式打印出来,但一直无法做到。该表格是学生姓名和成绩的列表。我希望它能以易于阅读的“成绩单”格式呈现。我使用的for循环打印出结果,但它是一个列式列表。

这是我当前设置的字典:

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

    },
}

这是我目前使用的for循环。
for i in student:
    for j in student[i]:
        print(j + " : " + str(student[i][j]))
    print("===========")

我希望以表格形式打印出来。
Name Grade Math English Physics Chemistry
Eddy   1    78      65     89        80
Jim    2    89      65     87        76
Jane   3    87      97     75        64

我尝试使用format()函数,但无法将其与嵌套字典配合使用。

我还尝试使用pandas并转换为pd.DataFrame,但无法使其正常工作。


看起来你应该学习Python中的“字符串格式化” - 请参阅页面pyFormat.info - furas
print() 自动换行 - 因此您可能需要使用 print(..., end="") 在一行中打印。 - furas
6个回答

5

首先:默认情况下,print()会在结尾处添加一个换行符,所以如果想要在一行中显示,则需要使用 print(..., end="")


我认为你应该学习字符串格式化 - 查看页面pyFormat.info。这样你可以更好地控制行内元素,而不是使用空格或\t

它需要同时处理所有元素,而不是使用内部的for循环,但这样可以更好地控制,并且需要更简单的代码。

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"]))

我使用items()方法获取一个学生的所有值,并且后面使用val["Name"]val["Grade"]等等来确保我将值放在正确的顺序中。

我使用{}来定义字符串中元素的位置,使用{:^5}来定义它应该使用具有5个字符的字段(如果文本较短,则会添加空格),^表示它应该在该字段中居中显示值。

Name Grade Math English Physics Chemistry
Eddy   1    78    65      89       80    
Jim    2    89    65      87       76    
Jane   3    87    97      75       64 

在字符串格式化中,您可以使用{}与任何其他文本一起使用来装饰表格。例如,您可以在字段之间放置|以创建表格。
+------+-------+------+---------+---------+-----------+
| 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('+------+-------+------+---------+---------+-----------+')

顺便说一下: 为了使其更通用,您可以使用列表'Name','Grade','Math','English','Physics','Chemistry']来决定显示哪些值。 您还可能需要计算列宽的代码,但这将是更复杂的代码。


4

这里有一个关于IT技术的内容需要翻译,涉及到 pandas ,就像你之前未能成功使用 pandas 一样,你可以使用 pandas.DataFrame.from_dict 并设置参数 orient=index

import pandas as pd

df = pd.DataFrame.from_dict(student, orient='index').reset_index(drop=True)

你得到

    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 表格

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 |
  • pandas相较于其他实现的优点是,数据现在以易于分析和绘图的格式呈现。
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')

enter image description here


3

我昨天刚好写了一篇。和大家分享一下。

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

    },
}

columns = list(student.values())[0].keys()
width = [len(col) for col in columns ]
print(" ".join(columns))
col_format = []
for w in width:
    if len(col_format) == 0:
        col_format.append("%s")
    else:
        col_format.append("%" + str(w) + "d")
str_col_format = " ".join(col_format)

for vals in student.values():
    values = list(vals.values())
    values[0] = f"{values[0].ljust(width[0])}"
    print(str_col_format % tuple(values))

1

可能不是最优雅的方式,但它确实有效。

print('\t'.join(['Name', 'Grade', 'Math', 'English', 'Physics', 'Chemistry']))
for stud in student:
    for topic in student[stud]:
        print(student[stud][topic], end='\t')
    print()

1
您可以将字典的 .values() 传递给 pandas.DataFrame
import pandas as pd

student = ...

df = pd.DataFrame(student.values())
print(df.to_string(index=False))

1
def get_keys(my_dict):
    keys = list(my_dict.keys())
    keys = my_dict[keys[0]].keys()
    keys = list(keys)
    return keys

# get headers
keys = get_keys(students)

# print header
for key in keys:
    print("%10s " %key, end="")
print("\n")

# print body
for values in students.values():
    for key in keys:
        print("%10s "%str(values[key]), end="")
    print("\n")

(这不一定会将名称打印为第一列)


谢谢,我会尝试测试上述解决方案。 - PythonCoder1981

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接