这是一种非常灵活的方法:
# a simple function to do our line-splitting per value
def split_value(value, width):
result = []
while len(value) > width: # while our string is longer than allowed
split_index = value.rfind(" ", 0, width)
if split_index == -1: # no space in our current chunk, we must do hard-break
split_index = width - 1 # set the split to our column width point
result.append(value[:split_index + 1]) # add the current slice as a sub-row
value = value[split_index + 1:] # remove the added slice from our data
if value: # there are leftovers from slicing, add them as the last piece
result.append(value)
return result
# and our main function...
def draw_table(data, columns, table_width, column_border=1):
column_data = [data[i::columns] for i in range(columns)] # split the data into columns
column_width = table_width // columns - column_border # max characters per column
column_template = ("{} " * (columns - 1)) + "{}" # a simple template for our columns
empty_value = " " * (column_width + column_border) # what to print when there's no value
rows = len(max(column_data, key=len)) # in case we have more data in some of the columns
for row in range(rows): # lets print our rows
row_data = [split_value(x[row], column_width) if len(x) > row else []
for x in column_data] # lets populate our row
subrows = len(max(row_data, key=len)) # number of subrows for the current row
for subrow in range(subrows): # lets go through each of them and print them out
print(column_template.format(*[x[subrow].ljust(column_width+column_border)
if len(x) > subrow else empty_value
for x in row_data])) # print our (split) row
这有点曲折,但可以可靠地完成工作,如果您阅读 cmets,这并不难理解。它应该完全符合您的要求(您想要的结果似乎与您列表中的数据不符):
listObj = ['Pre-Condition:', 'Condition:', 'Output:',
'Button is OFF', '-', 'Speed is not on',
'Button Enabled is OFF', 'Enabled is ON',
'Speed is on', 'Button Active is ON', 'Active is OFF',
'Hold steady true north', 'Button States is HOLD',
'Button States is ACCELERATOR OVERRIDE AND Set stuff is on <Stuff here>',
'Pedal to the medal here guys']
# table with three columns, two spaces between columns and of total width of 80 characters
draw_table(listObj, 3, 80, 2)
生产:
前置条件:条件:输出:
按钮关闭 - 速度未开启
按钮 启用为关 启用为开 速度为开
按钮 激活为 ON 激活为 OFF 保持稳定正北
按钮状态是 HOLD 按钮状态是此处的奖牌踏板
加速器覆盖伙计们
和设置的东西是
作为奖励,它支持不均匀列表,因此您可以执行以下操作:
listObj = ['Pre-Condition:', 'Condition:', 'Output:',
'Button is OFF', '-', 'Speed is not on',
'Button Enabled is OFF', 'Enabled is ON',
'Speed is on', 'Button Active is ON', 'Active is OFF',
'Hold steady true north', 'Button States is HOLD',
'Button States is ACCELERATOR OVERRIDE AND Set stuff is on...',
'Pedal to the medal here guys', "One extra value to prove the flow"]
draw_table(listObj, 3, 80, 2)
这将产生:
前置条件:条件:输出:
按钮关闭 - 速度未开启
按钮 启用为关 启用为开 速度为开
按钮 激活为 ON 激活为 OFF 保持稳定正北
按钮状态是 HOLD 按钮状态是此处的奖牌踏板
加速器覆盖伙计们
和设置的东西是...
一个额外的价值
证明流程
像可变列宽这样的未来升级应该不会那么困难,因为行数据拆分是外部的,因此可以添加任何大小。