在我去重新发明轮子之前,我想检查一下有人还没有拿出一些东西。
我有一个字符串列表,我需要以表格格式打印出来。我从表格中获取数据,这些数据可能在某些单元格中有一些长数据串。
如果我尝试根据最长的字符串来确定列宽,我最终会得到很大的列宽。
我想知道的是,是否存在将字符串数据附加到仍然与当前行对齐的另一行的某些内容(基本上将其视为强制自动填充的单元格)
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']
上面的列表最初是一个三乘五的表。所以我想用三列打印出所有内容。我遇到问题的地方是列表中倒数第二个字符串项。还有更多这样的,因为这是一个有点人为的例子。任何帮助将不胜感激。我之前遇到过这个问题,所以我想问一下,因为我确信其他人也有这个问题。
Pre-Condition Condition Output Button is OFF - Speed is not on Button Enabled is OFF Active is OFF Speed is on Button States is HOLD Button states is Pedal to the med ACCELERATOR OVERRIDE here guys AND Set stuff is on
答案 0 :(得分:1)
这是一个非常硬编码的尝试,你正在寻找什么。范围的错误检查也很少。我会让你处理:)
mylist = ['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']
def printCell(row, cellWidth):
while row != ["","",""]:
lineformat = ("{:"+str(cellWidth) + "} | ") * 3
cells=[]
for n, cell in enumerate(row):
p = cellWidth
if len(cell) > cellWidth :
p = cell[:cellWidth].rfind(" ")
if p == -1:
p = cellWidth
row[n] = cell[p:]
else:
row[n] = ""
cells.append(cell[:p])
print(lineformat.format(*cells))
def printColumns(alist, colCount, colWidth):
for n in range(0,len(alist)-1,colCount):
printCell(alist[n:n+colCount], colWidth)
print("-" * colWidth * colCount)
if __name__ == "__main__":
printColumns(mylist,3,30)
输出:
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 | Pedal to the medal here guys |
| OVERRIDE AND Set stuff is on | |
| <Stuff here> | |
------------------------------------------------------------------------------------------
修改强>
为什么不创建一个可以直接用excel打开的csv文件?
import csv
with open('output.csv', 'w') as f:
csvOut = csv.writer(f, delimiter=',')
for n in range(0,len(mylist)-1,3):
csvOut.writerow(mylist[n:n+3])
旁注
使用&#39; list&#39;这是不好的形式。作为变量。这可能与内置列表类型冲突,应该避免。
答案 1 :(得分:0)
以下是一种非常灵活的方式:
# 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
它有点扭曲,但可靠地完成工作,如果您阅读评论,并不难以理解。它应该产生你所要求的(你想要的结果似乎不适合你列表中的数据):
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)
产地:
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 Pedal to the medal here ACCELERATOR OVERRIDE guys AND Set stuff is on <Stuff here>
作为奖励,它支持不均衡的列表,因此您可以执行以下操作:
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)
将产生:
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 Pedal to the medal here ACCELERATOR OVERRIDE guys AND Set stuff is on... One extra value to prove the flow
可变列宽等未来升级不应该那么困难,因为行数据拆分是外部的,因此可以添加任何大小。