【问题标题】:How to justify columns using format function?如何使用格式函数证明列的合理性?
【发布时间】:2017-08-10 08:46:19
【问题描述】:

我有一个工作函数,它接受由列表组成的列表并将其输出为表格。我只是缺少某些间距和新行。我对格式化字符串(和一般的python)很陌生。如何使用格式化函数来修复我的输出?

例如:

>>> show_table([['A','BB'],['C','DD']])
'|  A   |   BB  |\n|    C   |   DD  |\n'


>>> print(show_table([['A','BB'],['C','DD']]))
|   A   |   BB  |
|   C   |   DD  |


>>> show_table([['A','BBB','C'],['1','22','3333']])
'|  A   |   BBB |   C               |\n|    1   |   22      |   3333    |\n'


>>> print(show_table([['A','BBB','C'],['1','22','3333']]))
|   A   |   BBB |   C               |
|   1   |   22      |   3333    |

我实际输出的是什么:

>>>show_table([['A','BB'],['C','DD']])
'| A | BB | C | DD |\n'

>>>show_table([['A','BBB','C'],['1','22','3333']])
'| A | BBB | C | 1 | 22 | 3333 |\n'


>>>show_table([['A','BBB','C'],['1','22','3333']])
| A | BBB | C | 1 | 22 | 3333 |

我肯定需要使用格式化功能,但我不确定如何使用?

这是我当前的代码(我的缩进实际上是正确的,但我对 stackoverflow 格式感到很糟糕):

def show_table(table):
 if table is None:
    table=[]
 new_table = ""
 for row in table:
    for val in row:
         new_table += ("| " + val + " ")
 new_table += "|\n"
 return new_table

【问题讨论】:

  • @Zero 感谢编辑!~
  • 在 SO 中进行代码格式化其实很容易;只需粘贴您的代码(使用 CTRL+C、CTRL+V 或其他),选择它,然后按 CTRL+K。
  • @ZeroPiraeus 我该如何格式化?
  • 有点……参与 :-) 见下文……

标签: python-3.x matrix output string-formatting tabular


【解决方案1】:

您的函数中确实存在缩进错误:行

new_table += "|\n"

应该进一步缩进,以便它发生在每行的末尾,而不是表的末尾。

旁注:如果您坚持每个缩进 4 个空格,您会更容易理解这种情况。这个和其他约定可以帮助你,在你使用 Python 的早期学习遵守它们的纪律是一个非常好的主意。 PEP 8 是一个让您熟悉的好资源。

“我需要什么”示例上的间距也相当混乱,这很不幸,因为间距是您问题的主题,但我从 this question 收集到您希望每列正确对齐,例如

>>> print(show_table([['10','2','300'],['4000','50','60'],['7','800','90000']]))
| 10   | 2   | 300   |
| 4000 | 50  | 60    |
| 7    | 800 | 90000 |

为此,您需要提前知道一列中每个项目的最大宽度是多少。这实际上有点棘手,因为您的表被组织成行而不是列,但是 zip() 函数可以提供帮助。以下是 zip() 所做的示例:

>>> table = [['10', '2', '300'], ['4000', '50', '60'], ['7', '800', '90000']]
>>> from pprint import pprint
>>> pprint(table, width=30)
[['10', '2', '300'],
 ['4000', '50', '60'],
 ['7', '800', '90000']]
>>> flipped = zip(*table)
>>> pprint(flipped, width=30)
[('10', '4000', '7'),
 ('2', '50', '800'),
 ('300', '60', '90000')]

如您所见,zip() 将行转换为列,反之亦然。 (现在不用太担心table之前的*;暂时解释得有点高级。记住你需要它)。

你用len()得到一个字符串的长度:

>>> len('800')
3

max() 获得列表中的最大项目数:

>>> max([2, 4, 1])
4

您可以将所有这些放在一个list comprehension 中,这就像一个构建列表的紧凑for 循环:

>>> widths = [max([len(x) for x in col]) for col in zip(*table)]
>>> widths
[4, 3, 5]

如果你仔细看,你会发现那一行实际上有两个列表推导:

[len(x) for x in col]

用列表col中每个项目x的长度创建一个列表,并且

[max(something) for col in zip(*table)]

为翻转(带有zip)表中的每一列创建一个最大值为something 的列表……其中something 是另一个列表理解。

当你第一次看到它时,这有点复杂,所以花点时间确保你了解发生了什么。

现在您已经有了每列的最大宽度,您可以使用它们来格式化您的输出。但是,为了做到这一点,您需要跟踪您所在的列,为此,您需要enumerate()。以下是enumerate() 的示例:

>>> for i, x in enumerate(['a', 'b', 'c']):
...     print("i is", i, "and x is", x)
... 
i is 0 and x is a
i is 1 and x is b
i is 2 and x is c

如您所见,遍历 enumerate() 的结果会为您提供两个值:列表中的位置和项目本身。

还和我在一起吗?有趣,不是吗?按下...

唯一剩下的就是实际的格式。 Python 的 str.format() 方法非常强大,而且过于复杂,无法在此答案中彻底解释。您可以使用它的一件事是将事物填充到给定的宽度:

>>> "{val:5s}".format(val='x')
'x    '

在上面的示例中,{val:5s} 表示“将val 的值作为字符串插入此处,并将其填充为 5 个空格”。您还可以将宽度指定为变量,如下所示:

>>> "{val:{width}s}".format(val='x', width=3)
'x  '

这些是您需要的所有部分……这里有一个使用所有这些部分的函数:

def show_table(table):
    if table is None:
        table = []
    new_table = ""
    widths = [max([len(x) for x in c]) for c in zip(*table)]
    for row in table:
        for i, val in enumerate(row):
            new_table += "| {val:{width}s} ".format(val=val, width=widths[i])
        new_table += "|\n"
    return new_table

……它正在行动中:

>>> table = [['10','2','300'],['4000','50','60'],['7','800','90000']]
>>> print(show_table(table))
| 10   | 2   | 300   |
| 4000 | 50  | 60    |
| 7    | 800 | 90000 |

我在这个答案中涵盖了相当多的基础。希望如果您详细研究此处给出的show_table() 的最终版本(以及整个答案中链接的文档),您将能够看到前面描述的所有部分是如何组合在一起的。

【讨论】:

  • 哦,如果你确实想知道zip()中的*到底是怎么回事,this answer会给出一个简短的解释。
  • 你是救生员!我真的很感谢你的解释。非常感谢!
  • 将 new_table="\n" 移过来时仍然显示缩进错误。
  • 确保你的缩进完全符合我的……c 未定义是一个谜;我想你一定打错了什么。我已经在 Python 2.7 和 3.x 的这个答案中测试了show_table(),它肯定可以工作。
  • 我能够修复缩进错误,但我仍然未能通过所有测试,因为我缺少第一组和最后两组之间的“\n”。 @零
猜你喜欢
  • 2023-03-27
  • 2017-09-11
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 2017-11-17
  • 1970-01-01
相关资源
最近更新 更多