【问题标题】:Print Nested Dictionary in Table Format以表格格式打印嵌套字典
【发布时间】:2021-04-09 06:33:33
【问题描述】:

我正在尝试以表格格式打印我的嵌套字典。但是一直没能做到。该表是学生姓名和学生成绩的列表。我希望它采用易于阅读的“报告卡”类型格式。我正在使用的 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 中了解string formatting - 请参阅页面pyFormat.info
  • print() 自动添加新行 - 所以您可能需要print(..., end="") 才能在一行中打印。
  • 仅供参考:彻底回答问题非常耗时。如果您的问题已解决,请通过接受最适合您的需求的解决方案表示感谢。 ✔ 位于答案左上角的向上/向下箭头下方。如果出现更好的解决方案,则可以接受新的解决方案。如果您的声誉超过 15,您还可以使用向上或向下箭头对答案的质量/有用性进行投票。 如果解决方案无法回答问题,请发表评论。 What should I do when someone answers my question?。谢谢。

标签: python pandas dictionary nested


【解决方案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()

【讨论】:

    【解决方案2】:

    昨天刚好写了一篇。分享它。

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

    【讨论】:

      【解决方案3】:

      首先:print() 默认在末尾添加new line,所以如果你想在一行中显示,那么你必须使用print(..., end="")


      我认为你应该学习string formatting - 请参阅页面pyFormat.info。这样,您可以更好地控制行中的元素,然后使用空格或\t

      它需要同时处理所有元素,而不是使用内部for-loop,但这提供了更好的控制并且需要更简单的代码。

      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 
      

      string formatting 中,您可以将{} 与任何其他文本一起使用来装饰表格。例如,您可以在要创建的字段之间放置|

      +------+-------+------+---------+---------+-----------+
      | 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('+------+-------+------+---------+---------+-----------+')
      

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

      【讨论】:

        【解决方案4】:
        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")
        

        (虽然这不一定将 Name 打印为第一列)

        【讨论】:

        • 谢谢,我会测试上述解决方案。
        【解决方案5】:

        您可以将dict中的.values()传递给pandas.DataFrame

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

        【讨论】:

          【解决方案6】:

          这是一个pandas 解决方案,正如您提到的尝试熊猫失败。您可以将pandas.DataFrame.from_dictorient=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')
          

          【讨论】:

            猜你喜欢
            • 2020-08-27
            • 2020-09-14
            • 1970-01-01
            • 2019-09-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-06-14
            相关资源
            最近更新 更多