简体   繁体   English

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

[英]How can i print this dictionary in form of a table?

i have a defaultdict like this: 我有一个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]})

and i want to print this in form of a table like this: 我想以表格形式打印此:

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

On the x-axis I want to output all days that occur in the dict next to each other. 在x轴上,我想输出在dict中彼此相邻的所有天数。 (each day only once) (每天只有一次)

On the Y-axis every time which occurs in the dict should be output to each other. 在Y轴上,每次在dict中发生的时间都应该相互输出。

The table should be filled with the ratio of False and True (maybe with statistics.mean()). 该表应填充为False和True的比率(也许带有statistics.mean())。

I only solved to print the axis with this code: 我只解决了用以下代码打印轴的问题:

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

The main challenge here is the format in which the data is given. 这里的主要挑战是给出数据的格式。 The (day,time) tuple as the key to the dict makes it difficult to index the dict to get the wanted value for each day/time combination. 由于(day,time)元组是字典的键,因此很难为该字典编制索引以获取每个日期/时间组合的期望值。 As shown in the code below, this can be fixed by transforming the data into a dict which can be indexed as data[day][time] , returning the percentage of true values. 如下面的代码所示,可以通过将数据转换为dict(可以索引为data[day][time] )并返回真实值的百分比来解决此问题。 Using a defaultdict , which you already mentioned in your question, avoids having to fill in zeros for missing values. 使用您已经在问题中提到的defaultdict ,可以避免为缺少的值填充零。

Computing the percentage given a list of boolean values can be done using sum : each True is counted as one, and each False as zero. 可以使用sum来计算给定布尔值列表的百分比:将每个True计为1,将每个False为零。 Divide by the length to get the mean, and multiply by 100 to get the percentage. 除以长度即可得出平均值,再乘以100即可得出百分比。 I used sum(bool(v) for v in lst) in case some non-bool values (like integers) are passed in. If you want, you can change it to just sum(lst) . 如果传入了一些非布尔值(如整数),我会使用sum(bool(v) for v in lst) 。如果需要,可以将其更改为sum(lst)

The output of the code below matches your desired output. 以下代码的输出与所需的输出匹配。

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)

Try this: 尝试这个:

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

Output: 输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM