自动化无聊的事情,第 6 章 Table 打印机

Automate the Boring Stuff, Chapter 6 Table Printer

我正在关注 http://automatetheboringstuff.com/chapter6/
在页面的最底部是关于格式化表格的练习。

这是我的代码:

tableData = [['apples', 'oranges', 'cherries', 'banana'],
         ['Alice', 'Bob', 'Carol', 'David'],
         ['dogs', 'cats', 'moose', 'goose']]

def printTable(table):
    colWidths = [0] * len(table)

    for line in table:
        max = 0
        for word in line:
            if len(word) > max:
                max = len(word)
        colWidths[table.index(line)] = max

    for a in range(len(table)-2):
        for b in range(len(table[0])):
            print(table[a][b].rjust(colWidths[0])+table[a+1][b].rjust(colWidths[1])+table[a+2][b].rjust(colWidths[2]))

    """
    print(table[0][0].rjust(colWidths[0]), table[1][0].rjust(colWidths[1]), table[2][0].rjust(colWidths[2]))
    print(table[0][1].rjust(colWidths[0]), table[1][1].rjust(colWidths[1]), table[2][1].rjust(colWidths[2]))
    print(table[0][2].rjust(colWidths[0]), table[1][2].rjust(colWidths[1]), table[2][2].rjust(colWidths[2]))
    print(table[0][3].rjust(colWidths[0]), table[1][3].rjust(colWidths[1]), table[2][3].rjust(colWidths[2]))
    """
    print()

printTable(tableData)

注释掉的行按照应有的格式格式化所有内容。实际代码没有。为了使其格式正确,我需要为每列添加 1 到 .rjust()(例如,如果有 100 列,我必须添加 .rjust(colWidths[1]+99))。

为什么我只是手动打印时它似乎工作正常时会发生这种情况?

for循环中的打印语句使用字符串连接:

print(table[a][b].rjust(colWidths[0])+table[a+1][b].rjust(colWidths[1])+table[a+2][b].rjust(colWidths[2]))

连接在内存中创建每个字符串,然后在它们的末端将它们组合在一起形成一个新字符串。项目之间不会添加空格,这就是为什么您需要为它之前的每一列添加一个字符。

您代码中注释掉的行使用逗号分隔参数:

"""
print(table[0][0].rjust(colWidths[0]), table[1][0].rjust(colWidths[1]), table[2][0].rjust(colWidths[2]))
print(table[0][1].rjust(colWidths[0]), table[1][1].rjust(colWidths[1]), table[2][1].rjust(colWidths[2]))
print(table[0][2].rjust(colWidths[0]), table[1][2].rjust(colWidths[1]), table[2][2].rjust(colWidths[2]))
print(table[0][3].rjust(colWidths[0]), table[1][3].rjust(colWidths[1]), table[2][3].rjust(colWidths[2]))
"""

用逗号分隔项目的打印语句,使用 space 来分隔它们。这可能就是您的列正确排列的原因。

This answer 解释得更详细。

你遇到困难的代码部分与我的和我的工作非常相似。

def printTable(List):
    colWidths = [0] * len(tableData)

    for line in range(len(tableData)):
        for word in range(len(tableData[line])):
            if colWidths[line] <= len(tableData[line][word]):
                colWidths[line] = len(tableData[line][word])
            else:
                colWidths[line] = colWidths[line]

#this is the part where you struggled
    for li in range(len(tableData[0])):
        for i in range(len(tableData)):
            print(tableData[i][li].rjust(colWidths[i]), end =" ")
        print()

由于每个单独列表的内容定义了每列的必要宽度,您可以在循环中执行 len(max(tableData[x])) 以获得每列的最大长度。将其附加到列表中,它很容易传输:

tableData = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose']]

colWidth = []

def printTable(table):
    for x in range(len(table)):
        colWidth.append(len(max(table[x],key=len))+1)       

    for x in range(len(table[0])):
        for i in range(len(table)):
            print (table [i][x].rjust(colWidth[i]), end = " ")
        print()

printTable(tableData)

这是我的代码,经过一个星期的困扰和追逐我的梦想,它终于可以工作了:

tableData = [['apples', 'oranges', 'cherries', 'banana'],
             ['Alice', 'Bobolon', 'Carolina', 'Davidovv'],
             ['dogsee', 'puscats', 'moosara', 'gooseano']]

def printTable(table):
    colwidths=[0]*len(table)
    for i in range(len(table)):
        for j in range(len(table[i])):
            if len(table[i][j])>colwidths[i]:
                colwidths[i]=len(table[i][j])

    for line in range(len(table[0])): #PYTHON PRINTS LINE PER LINE. NOT COLUMN PER COLUMN.ABOUT TABLE[0]: IT IS ESTABLISHED THAT ALL ITEMS IN TABLEDATA WILL HVE THE SAME LENGTH, SO THAT IT DOESNT MATTER WETHER YOU PUT [0], [1] OR [2] BECAUSE THEY ALL HAVE LENGTH OF 4 ITEMS (IN CASE OF THE TABLEDATA LIST
        for column in range(len(table)): #THERE ARE AS MANY COLUMNS AS ITEMS(LISTS) IN TABLEDATA
            print(table[column][line].ljust(colwidths[column]*2),end=" ") #NOW, WE PRINT THE FIRST WORD OF THE FIRST COLUMN, FOLLOWED BUYT THE FIRST WORD OF THE SECOND COLUMN AND SO ON. .END= HELPS WITH NOT HAVING TO CONCATENATE THESE AND KEEPING ITEMS IN THE SAME LINE.
        print() #WITHOUT THIS PRINT (WHICH PRINTS A NEW LINE), ALL ITEMS WOULD BE IN THE SAME LINE, DUE TO THE PREVIOS .END=

printTable(tableData)

下面是我用来在 table 中查找最长字符串并打印 table

的代码
tableData = [['apples', 'orange', 'cherries', 'banana'],
         ['Alice', 'Bob', 'Carol', 'David'],
         ['dogs', 'cats', 'moose', 'goose']]

def printTable(table):

    strName = ''
    maxLen = -1
    # Find longest string in table
    for y in range(len(table[0])):
                 
            for x in range(len(table)): 
                   strName = table[x][y]
                   if len(strName) > maxLen:
                   maxLen = len(strName) + 1

    # Print table   
    for y in range(len(table[0])):
    
            newTable = ''           
            for x in range(len(table)): 
                newTable = newTable + (table[x][y].ljust(maxLen))                 
            print(newTable)
                  

printTable(tableData) # Call function
tableData = [['apples', 'oranges', 'cherries', 'bananas'],
            ['Alice', 'Bob', 'Caroline', 'David'],
            ['dogs', 'cats', 'moose', 'goose']]
#To calculate the length of the longest word in the table
colwid = 0
for j in range(len(tableData[0])):
    for i in range(len(tableData)):
        if colwid < len(tableData[i][j]):
            colwid = len(tableData[i][j])
        i = i + 1
    j = j + 1
#Print the table with each field left justified with column length from above
for j in range(len(tableData[0])):
    for i in range(len(tableData)):
        print(tableData[i][j].ljust(colwid), end=' ')
        i = i + 1
    j = j + 1
    print()

这是我的解决方案。我有一个更简单的函数适用于给定数据(3 列,每列 4 行),但后来我开始想知道如果输入一个具有不同长度行的二维数组会发生什么,所以我做了一些调整以适应这些情况。

tableData = [['apples', 'oranges', 'cherries', 'bananas', 'kiwis'],
             ['Alice', 'Bob', 'Carol', 'David'],
             ['dogs', 'cats', 'moose', 'goose'],
             ['rocks']]
     
def printTable(data):
    rows = len(max(data, key=len)) # get the number of rows based on longest array (if variable)
    cols = len(data) # get the number of columns
    colWidths = [0] * cols # set column widths to zero
    for c in range(cols):
        colWidths[c] = len(max(data[c]))+2 # get length of longest word in each column and assign width to columns (added a little extra)
        diff = rows - len(data[c]) # Check for rows with incomplete data (fewer entries than the longest row)
        if diff < rows:
            for x in range(diff):
                data[c].append('') # Add blank strings to create rows of equal length
    for j in range(rows):
        for i in range(cols):
            cw = colWidths[i]
            print(data[i][j].rjust(cw), end='')
        print() # New row
printTable(tableData)    

这是自动化无聊的东西中的一个令人沮丧的项目,但我认为我让它变得太复杂了。与我在这里找到的许多答案相同。以下是我认为作者可能想要的,简单明了。我将语句的嵌套和变量的创建保持在最低限度。

tableData = [['apples', 'oranges', 'cherries', 'banana'],
            ['Alice', 'Bob', 'Carol', 'David'],
            ['dogs', 'cats', 'moose', 'goose']]

# function to print right-justified table
def printTable(table):
    # create list for no. of columns
    colWidths = [0] * len(tableData)

    # find longest string in each column
    for col in range(len(table)):
        for i in table[col]:
            if len(i) > colWidths[col]:
                colWidths[col] = len(i)

    # print columns
    for row in range(len(table[0])):
        for col in range(len(table)):
            print(table[col][row].rjust(colWidths[col]), end=' ')
        print()

printTable(tableData)