在 Python 中使用 rjust() 并减少 for 循环

Posted

技术标签:

【中文标题】在 Python 中使用 rjust() 并减少 for 循环【英文标题】:Using rjust() and reducing for loops in Python 【发布时间】:2019-01-26 22:59:52 【问题描述】:

我正在尝试制定一个接受字符串列表列表的函数 并将其显示在一个组织良好的表格中,每列右对齐。 假设所有内部列表将包含相同数量的字符串。 例如,该值可能如下所示:

tableData = [['apples', 'oranges', 'cherries', 'banana'],

['Alice', 'Bob', 'Carol', 'David'],

['dogs', 'cats', 'moose', 'goose']]

您的函数将打印以下内容(右对齐):

    apples Alice   dogs

   oranges   Bob   cats

  cherries Carol  moose

    banana David  goose

使用给定的提示,我已经到达:

def printable(tableData):
    newTable = np.zeros((len(tableData[0]),len(tableData)))
    colWidths = [0] * len(tableData)
    for i in range(0,len(tableData)):
        colWidths[i] = max(tableData[i], key=len)
    largest = max(colWidths, key=len)
    for i in range(0,len(tableData)):
        for j in range(0,len(tableData[0])):
            newTable[i][j] = tableData[j][i].rjust(len(largest))

我对没有感到震惊。的 for 循环。作为一个初学者,我仍然摆脱了“for-loop”模式。另外,我正在考虑解决这个问题的最佳攻击形式。谢谢。

【问题讨论】:

【参考方案1】:

这是在普通 Python 中执行此操作的一种方法。我们使用zip来转置表格,这样我们就可以得到每列的最大宽度。

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

# Determine the width of each column
widths = [max(map(len, column)) for column in zip(*table_data)]
new_table = [[s.rjust(w) for s, w in zip(row, widths)]
    for row in table_data]

for row in new_table:
    print(row)

输出

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

如果您真的不需要新的 2D 列表,而只想打印数据,可以执行以下操作:

for row in table_data:
    print(*(s.rjust(w) for s, w in zip(row, widths)))

输出

apples oranges cherries banana
 Alice     Bob    Carol  David
  dogs    cats    moose  goose

这是一个转换表格的新版本。

widths = [max(map(len, row)) for row in table_data]
new_table = [[s.rjust(w) for s, w in zip(row, widths)] for row in zip(*table_data)]
for row in new_table:
    print(row)

输出

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

【讨论】:

zip 正是我在玩弄的 :) 谢谢! 我刚刚注意到输出与所需的不一样?现在正在努力。 @db18 好的。我看到您希望输出转置。 :oops: 我会添加一个新版本。 每当我看到最后一个用于打印的for 循环:collections.deque((print(row) for row in new_table), maxlen=0) 时,我都会有这样的冲动。不过我不积极推荐它:) @MadPhysicist 对于我的私人用途,我很想使用print(*map(' '.join, new_table), sep='\n'),但我尽量让事情变得更简单。 ;)【参考方案2】:

to_stringindex=Falsetransposesplitlines 的 Pandas 组合

有一个header=None 选项,但由于某种未知原因,它弄乱了对齐方式。所以我留下标题并用splitlines[1:] 关闭它

import pandas as pd
print('\n'.join(pd.DataFrame(table_data).T.to_string(index=False).splitlines()[1:]))

  apples  Alice   dogs
 oranges    Bob   cats
cherries  Carol  moose
  banana  David  goose

f 字符串 + str.format

构造一个基于最大字符串长度的str.format 函数。 灵感来自PM 2Ring

f = '  '.join([f":>max(map(len, r))" for r in table_data]).format
print('\n'.join([f(*t) for t in zip(*table_data)]))

  apples  Alice   dogs
 oranges    Bob   cats
cherries  Carol  moose
  banana  David  goose

详情

这个:

'  '.join([f":>max(map(len, r))" for r in table_data])

产生一个如下所示的字符串:

':>8  :>5  :>5'

8, 5, 5 是每行的最大字符串长度。我通过在末尾附加 .format 将其转换为格式函数。它现在是一个接受 3 个位置参数并按规定间距格式化字符串的函数。

【讨论】:

【参考方案3】:

我以为你必须自己编写算法,但在你的尝试中你使用了numpy,所以我假设你也可以使用pandas

您可以将数据加载到数据框中,转置并使用 pandas DataFrame 类中已构建的 __repr__

换句话说,

pd.DataFrame(arr).T.__repr__()

产生

'          0      1      2\n0    apples  Alice   dogs\n1   oranges    Bob   cats\n2  cherries  Carol  moose\n3    banana  David  goose'

这样,如果你print它,你会得到

          0      1      2
0    apples  Alice   dogs
1   oranges    Bob   cats
2  cherries  Carol  moose
3    banana  David  goose

如果您不想打印列 ID,可以使用 __repr__ 输出

print('\n'.join([x[1:] for x in df.__repr__().split('\n')[1:]]))


    apples  Alice   dogs
   oranges    Bob   cats
  cherries  Carol  moose
    banana  David  goose

【讨论】:

【参考方案4】:
tableData = [
    ['apples', 'oranges', 'cherries', 'banana'],
    ['Alice', 'Bob', 'Carol', 'David'],
    ['dogs', 'cats', 'moose', 'goose']
]

# Determine maximum column width
colWidth = 0
for x in tableData:
    colWidth = max(colWidth, len(max(x, key=len)))

# Use zip to "flip" your rows and columns
# Note that the * first unpacks your list of lists 

for row in zip(*tableData):
     # Join each row element together into a string, right justifying each element to your column width as you go
    print ''.join([ele.rjust(colWidth) for ele in row])

【讨论】:

以上是关于在 Python 中使用 rjust() 并减少 for 循环的主要内容,如果未能解决你的问题,请参考以下文章

Python:str.ljust()str.rjust()str.center()函数

python3----ljust rjust center

python 的rjust函数

python ljust,rjust,center,zfill对齐使用方法

rjust()方法

47-python基础-python3-字符串-常用字符串方法