如何使用格式函数证明列的合理性?
How to justify columns using format function?
我有一个工作函数,它接受一个由列表组成的列表并将其输出为 table。我只是缺少某些间距和新行。我对格式化字符串(和一般的 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 |
我肯定需要使用格式功能,但我不确定如何使用?
这是我当前的代码(我的缩进实际上是正确的,但我对 Whosebug 格式很糟糕):
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
您的函数中确实存在缩进错误:行
new_table += "|\n"
应该进一步缩进,以便它出现在每一行的末尾,而不是在 table.
的末尾
Side note: you'll catch this kind of thing more easily if you stick to 4 spaces per indent. This and other conventions are there to help you, and it's a very good idea to learn the discipline of keeping to them early in your progress with Python. PEP 8 is a great resource to familarise yourself with.
您的 "what I need" 示例中的间距也相当混乱,这很不幸,因为间距是您问题的主题,但我从 了解到您希望每一列都正确对齐,例如
>>> print(show_table([['10','2','300'],['4000','50','60'],['7','800','90000']]))
| 10 | 2 | 300 |
| 4000 | 50 | 60 |
| 7 | 800 | 90000 |
为此,您需要事先知道列中每个项目的最大宽度是多少。这实际上有点棘手,因为您的 table 被组织成行而不是列,但是 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
的列表 table ……其中 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}
表示 "insert the value of val
here as a string, padding it out to 5 spaces"。您还可以将宽度指定为变量,如下所示:
>>> "{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()
的最终版本(以及整个答案中链接的文档),您将能够看到前面描述的所有部分是如何组合在一起的。
我有一个工作函数,它接受一个由列表组成的列表并将其输出为 table。我只是缺少某些间距和新行。我对格式化字符串(和一般的 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 |
我肯定需要使用格式功能,但我不确定如何使用?
这是我当前的代码(我的缩进实际上是正确的,但我对 Whosebug 格式很糟糕):
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
您的函数中确实存在缩进错误:行
new_table += "|\n"
应该进一步缩进,以便它出现在每一行的末尾,而不是在 table.
的末尾Side note: you'll catch this kind of thing more easily if you stick to 4 spaces per indent. This and other conventions are there to help you, and it's a very good idea to learn the discipline of keeping to them early in your progress with Python. PEP 8 is a great resource to familarise yourself with.
您的 "what I need" 示例中的间距也相当混乱,这很不幸,因为间距是您问题的主题,但我从
>>> print(show_table([['10','2','300'],['4000','50','60'],['7','800','90000']]))
| 10 | 2 | 300 |
| 4000 | 50 | 60 |
| 7 | 800 | 90000 |
为此,您需要事先知道列中每个项目的最大宽度是多少。这实际上有点棘手,因为您的 table 被组织成行而不是列,但是 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
的列表 table ……其中 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}
表示 "insert the value of val
here as a string, padding it out to 5 spaces"。您还可以将宽度指定为变量,如下所示:
>>> "{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()
的最终版本(以及整个答案中链接的文档),您将能够看到前面描述的所有部分是如何组合在一起的。