如何以表格形式打印此词典?

时间:2019-05-22 06:03:14

标签: python python-3.x dictionary printing defaultdict

我有一个像这样的defaultdict:

{('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轴上,我想输出dict中彼此相邻的所有日期。 (每天只有一次)

在dict中每次出现的Y轴上都应该相互输出。

该表应使用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}")

2 个答案:

答案 0 :(得分:1)

这里的主要挑战是给出数据的格式。 (day,time)元组作为字典的键,使得很难为字典编制索引以获取每个日期/时间组合的期望值。如下面的代码所示,可以通过将数据转换为可索引为data[day][time]的字典来返回固定值的百分比来解决此问题。使用您在问题中已经提到的defaultdict,可以避免为缺失的值填写零。

可以使用sum计算给定布尔值列表的百分比:每个True被计为1,每个False被计为零。除以长度即可得出平均值,再乘以100即可得出百分比。我使用了sum(bool(v) for v in lst),以防传入一些非布尔值(例如整数)。如果需要,可以将其更改为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)

答案 1 :(得分:0)

尝试一下:

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]}


# get unique times
time = []
for item in data:
    time.append(item[1])

time_list = list(set(time))
sorted_time = sorted(time_list, key=float)

# set days
days = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag']

# create data sets
proper_data = []
for time in sorted_time:
    for day in days:
        for key, value in data.items():
            if key[1] == time and key[0] == day:
                if value.count(True) == 1:
                    proper_data.append('50')
                elif value.count(True) == 2:
                    proper_data.append('100')
        else:
            proper_data.append('0')
    proper_data.append(time)


# remove additional items
item_indexes = [n+1 for n,x in enumerate(proper_data) if x=='50' or x =='100']

for index in sorted(item_indexes, reverse=True):
    del proper_data[index]

# slice data into parts
final_data = []
for i in range(int(len(proper_data)/8)):
    final_data.append(proper_data[(8*i):(8*(i+1))])


# add time to names
days.append('Time')

# print data
final_data = [days] + final_data
for item in final_data:
    print("{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}{:<10}".format(item[0], item[1], item[2], item[3], item[4], item[5], item[6], item[7]))

输出:

Montag    Dienstag  Mittwoch  DonnerstagFreitag   Samstag   Sonntag   Time      
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         100       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