首页 > 解决方案 > 我如何以表格的形式打印这本字典?

问题描述

我有一个这样的默认字典:

{('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}")

标签: pythonpython-3.xdictionaryprintingdefaultdict

解决方案


这里的主要挑战是给出数据的格式。作为 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)

推荐阅读