python - 我如何以表格的形式打印这本字典?
问题描述
我有一个这样的默认字典:
{('Montag', '17.30'): [True, False], ('Dienstag', '16.30'): [True, False], ('Mittwoch', '15.30'): [True, False], ('Donnerstag', '14.30'): [True, False, False, True], ('Freitag', '13.30'): [True, False], ('Samstag', '12.30'): [True, False], ('Sonntag', '11.30'): [True, False], ('Sonntag', '17.30'): [False, True], ('Samstag', '16.30'): [False, True], ('Freitag', '15.30'): [False, True], ('Mittwoch', '13.30'): [False, True], ('Dienstag', '12.30'): [False, True], ('Montag', '11.30'): [False, True], ('Donnerstag', '16.30'): [False, True], ('Samstag', '11.25'): [True,True]})
我想以这样的表格形式打印它:
Montag Dienstag Mittwoch Donnerstag Freitag Samstag Sonntag
0 0 0 0 0 100 0 11.25
50 0 0 0 0 0 50 11.30
0 50 0 0 0 50 0 12.30
0 0 50 0 50 0 0 13.30
0 0 0 50 0 0 0 14.30
0 0 50 0 50 0 0 15.30
0 50 0 50 0 50 0 16.30
50 0 0 0 0 0 50 17.30
在 x 轴上,我想输出字典中相邻的所有日期。(每天只有一次)
在 Y 轴上,dict 中出现的每次都应该相互输出。
该表应填写 False 和 True 的比率(可能使用 statistics.mean())。
我只解决了使用以下代码打印轴:
WOCHENTAGE = {0: "Montag",
1: "Dienstag",
2: "Mittwoch",
3: "Donnerstag",
4: "Freitag",
5: "Samstag",
6: "Sonntag"}
set_for_day = set()
set_for_time = set()
for k, v in testdict.items():
set_for_day.add(k[0])
set_for_time.add(k[1])
order = list(WOCHENTAGE.values())
for day in sorted(set_for_day, key = lambda x: order.index(x)):
print(f"{day} ", end ="")
print()
for times in sorted(set_for_time):
print(f" {times}")
解决方案
这里的主要挑战是给出数据的格式。作为 dict 键的(day,time)
元组使得索引 dict 以获取每个日期/时间组合的所需值变得困难。如下面的代码所示,可以通过将数据转换为可以索引为的 dict 来解决此问题data[day][time]
,返回真值的百分比。使用defaultdict
您在问题中已经提到的 a 可以避免为缺失值填充零。
计算给定布尔值列表的百分比可以使用sum
:每个True
都计为 1,每个都计False
为 0。除以长度得到平均值,乘以 100 得到百分比。我sum(bool(v) for v in lst)
在传入一些非布尔值(如整数)的情况下使用。如果需要,可以将其更改为 just sum(lst)
。
下面代码的输出与您想要的输出相匹配。
from collections import defaultdict
# The example data.
data = {
('Montag', '17.30'): [True, False],
('Dienstag', '16.30'): [True, False],
('Mittwoch', '15.30'): [True, False],
('Donnerstag', '14.30'): [True, False, False, True],
('Freitag', '13.30'): [True, False],
('Samstag', '12.30'): [True, False],
('Sonntag', '11.30'): [True, False],
('Sonntag', '17.30'): [False, True],
('Samstag', '16.30'): [False, True],
('Freitag', '15.30'): [False, True],
('Mittwoch', '13.30'): [False, True],
('Dienstag', '12.30'): [False, True],
('Montag', '11.30'): [False, True],
('Donnerstag', '16.30'): [False, True],
('Samstag', '11.25'): [True,True]
}
# Week days, in order.
WEEK_DAYS = [
"Montag",
"Dienstag",
"Mittwoch",
"Donnerstag",
"Freitag",
"Samstag",
"Sonntag"
]
# Given a list of values, return the percentage that are truthy.
def percentage_true(lst):
return 100 * sum(bool(v) for v in lst) / len(lst)
# The list of days and times present in the data.
present_days = list(set(k[0] for k in data.keys()))
present_times = list(set(k[1] for k in data.keys()))
# Sort these days based on WEEK_DAYS.
present_days.sort(key = WEEK_DAYS.index)
# Sort the times by converting to minutes.
present_times.sort(key = lambda s: 60 * int(s[:2]) + int(s[3:]))
# Re-organize the data such that it can be indexed as
# data[day][time] => percentage. Use a defaultdict to
# return 0 for absent values.
data = {
day: defaultdict(lambda: 0, {
k[1]: percentage_true(v)
for k, v in data.items() if k[0] == day
})
for day in set(k[0] for k in data.keys())
}
# Print the header.
for day in present_days:
print(day, end=" ")
print()
# For printing, find the lengths of the day names, and the
# formats required for .format().
day_lengths = [len(s) for s in present_days]
perc_formats = ["{{:<{}.0f}}".format(l) for l in day_lengths]
# Print the values row-by-row.
for time in present_times:
for day, fmt in zip(present_days, perc_formats):
print(fmt.format(data[day][time]), end=" ")
print(time)
推荐阅读
- xpath - 选择系列中所有(动态创建的)项目匹配属性的节点
- c - 如何在 GCC 中启用已初始化但未使用的错误
- javascript - 如何从 HTML 访问 CSV 文件并将其保存在数组中(仅使用 Javascript)
- java - 如何在不打开新阶段的情况下通过关闭阶段并返回具有值的上一个阶段?
- android - 显示用户离线的最佳方式 - Firebase Android
- c++ - c++ 从父类实例化一个受保护的成员
- python - 如何通过命令行保存到列表中
- sql - 在 Oracle 18C 中触发问题,“声明内容”
- typescript - 打字稿:如果字符串在数组中,则切换
- node.js - 全局实例的某些属性不会被扩展运算符或节点 v12 中的 Object.assign 复制