打印中的制表符在Python中不一致。

16

我想在打印时使用真正的制表符,但\t只会产生空格。

 first:ThisIsLong         second:Short
 first:Short         second:ThisIsLong
 first:ThisIsEvenLonger         second:Short

我该如何修复它,以便我可以让所有的第一和第二对齐呢?例如:

 first:ThisIsLong         second:Short
 first:Short              second:ThisIsLong
 first:ThisIsEvenLonger   second:Short

抱歉,我还不太熟悉堆栈溢出,暂时还不能换行。 - ewan
你展示的东西就是你期望在真正的标签页中看到的东西。 - John Coleman
真正的制表符会捕捉到一个点。 - ewan
但是——并不总是达到你所期望的程度。请看我的回答。 - John Coleman
5个回答

22

你可以使用格式化来对齐字符串。例如,您可以告诉Python第一列应该是20个字符长,第二列应该是10个字符长,左对齐。

例如:

string_one = 'first:ThisIsLong'
string_two = 'second:Short'

print( '{:<20s} {:<10s}'.format(string_one, string_two) )

将打印:

first:ThisIsLong     second:Short

第一个格式化描述符({:<20s})的意思是:

'<' 左对齐,20 至少20个字符,s 因为它是一个字符串。


如果字符串一不总是相同的,我该如何做到这一点? - ewan
@ewan如果您能合理估计最长字符串的长度,那么只需将该数字插入格式描述符{:<100s}即可。否则,您将不得不找出最大的字符串长度并使用它。 - mjwunderlich
提示:您可以格式化格式描述符以动态添加长度:'{:<%ds}' % 100 将输出 {:<100s} - mjwunderlich

9

我建议不要使用制表符(\t),而是采用printf格式化字符串或者str.format进行字符串格式化:

rows = [
    ['first:ThisIsLong', 'second:Short'],
    ['first:Short', 'second:ThisIsLong'],
    ['first:ThisIsEvenLonger', 'second:Short'],
]
for first, second in rows:
    print('%-25s %s' % (first, second))

或者

print('{:<25} {}'.format(first, second))

6

计算每列所需的最大宽度,然后使用字符串格式化来组成指定所需宽度的格式:

data = [['first:ThisIsLong', 'second:Short'],
        ['first:Short', 'second:ThisIsLong'],
        ['first:ThisIsEvenLonger', 'second:Short']]

widths = [max([len(item) for item in col]) for col in zip(*data)]
fmt = ''.join(['{{:{}}}'.format(width+4) for width in widths])
for row in data:
    print(fmt.format(*row))

产出率
first:ThisIsLong          second:Short         
first:Short               second:ThisIsLong    
first:ThisIsEvenLonger    second:Short         

5
The Python print函数将字符串发送到标准输出。标准输出对这些字符串的处理取决于输出设备。默认情况下,\t 的解释是前进到下一个制表位,按照惯例,制表位是在\t出现的位置(从左边开始计算字符位置0)之后的下一个8的倍数的字符位置。例如,如果我运行:
babynames = [('kangaroo', 'joey'), ('fox', 'kit'), ('goose','gosling')]
for x,y in babynames: print(x + '\t' + y)

我得到:

kangaroo        joey
fox     kit
goose   gosling

我在IDLE中看到了上面的内容。 kangaroo 占据列0-7。 \t 位于列8,因此制表符后面的下一个8的倍数(下一个制表符停止) 是在第16列 - 这确实是您看到的 joey 的位置。在接下来的两行中 - 第一个单词后面的下一个制表符停止位于第8列。这表明(至少在IDLE shell中)Python 正在使用真正的制表符。
在这种情况下,“制表符”有点麻烦。它们只能用于将长度可变的字符串数据与某些令人讨厌的困难对齐。正如其他人所指出的,解决方案是不使用制表符,而是使用 format

我刚刚测试了一下,对我来说 \t 只会添加8个空格。 - ewan
实际上很抱歉,它确实可以工作,但对于我使用它的目的来说并不适用。 - ewan
@ewan 一些集成开发环境有一个选项,可以自动将制表符转换为空格,可能默认启用。这可能是你看到的情况。不同的编辑器/ shell 处理 \t 的方式不同。这与 Python 实际上没有太大关系。请查看您正在使用的编辑器选项。 - John Coleman

4

最Pythonic的方式:

string_one = 'first:ThisIsLong'
string_two = 'second:Short'

print(f'{string_one:<20s} {string_two:<10s}')

你可以使用F-string(格式字符串)来对齐字符串。例如,您可以告诉python第一列应为20个字符长,第二列应为10个字符长,并且左对齐。
使用这个F-string将打印:
first:ThisIsLong     second:Short

解释

在这个示例中: f'{insert_variable_here:<20s}'

:<20s 是格式。

: 表示将其前面的所有内容进行格式化,具体如下:

< 左对齐,20 至少保留20个字符空间,s 是字符串类型。

感谢 mjwunderlich 的答案格式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接