如何使用格式函数来证明列的合理性?

时间:2017-03-18 22:08:39

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

我有一个工作函数,它采用由列表组成的列表并将其作为表输出。我只是缺少一定的间距和新的线条。我对格式化字符串(以及一般的python)很新。我如何使用format函数来修复输出?

例如:

>>> 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

1 个答案:

答案 0 :(得分:2)

你的功能实际上有一个缩进错误:行

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]

在列表x中列出每个项col的长度,

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

为翻转的(something)表格中的每一列创建一个最大值zip的列表...其中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()的最终版本(以及整个答案中链接的文档),您将能够看到之前描述的所有部分如何组合在一起。 / p>