如何使用空格将字符串填充为固定长度

105

我相信这个问题已经在很多地方都有涉及,但是我不知道我要做的确切操作名称,所以我无法查找。我已经阅读了一本官方的Python书籍30分钟,试图找出如何做到这一点。

问题:我需要将一个字符串放入特定长度的“字段”中。

例如,如果名称字段为15个字符长,而我的名字是John,那么我将得到“John”,后面跟着11个空格,以创建15个字符的字段。

我需要这个功能适用于任何输入到变量“name”的字符串。

我知道这可能是某种格式化的形式,但我找不到确切的方法来实现这一点。帮助将不胜感激。


有关效率的注释。像 John 这样的短字符串是被存储在内部的,但大多数生成的字符串不是,这可能会导致增加内存压力,尤其是在紧密循环中使用或重复执行以重新对齐相同的字符串。已存储:name = 'John'; name is 'John' — 未存储:"{:<15}".format("John") 不等于 'John '也未存储:"John".ljust(15) 不等于 'John '("John"+" ")[:15] 不等于 'John 'name = "John"; while len(name) < 15: name += " " name 不等于 'John ' (假装 HTML 没有折叠。;) - amcgregor
10个回答

159

使用format非常简单:

>>> a = "John"
>>> "{:<15}".format(a)
'John           '

1
@GamesBrainiac,对于这种简单的情况来说,format可能有些过度设计,但一旦理解了它,它是如此强大,以至于它值得付出最初的学习成本!所以我给它点赞。 - Joël
12
如果文本长度超过15个字符,format 不会对其进行截断。若要实现截断,请使用 '{:<15}'.format(a[:15]) - ChaimG
16
从Python版本3.6开始,您可以使用f字符串(f-strings)来代替string.format()函数。例如:f"{a:<15}" - alec_djinn
如果我想像这样打印 "Hello %s!" % name,而不是使用 format,该怎么用呢? - hipoglucido
1
不错!这将在字符串右侧添加空格。这个方法能否用于从左侧填充字符串,或者用其他东西而不是空格填充它?例如,如果我想要将非负整数从左侧填充零以达到特定长度,该怎么做呢? - HelloGoodbye
5
我在这里找到了自己问题的答案。如果您想要右对齐,只需将 < 替换为 >,并在 <> 之前输入填充字符即可。例如,'{:0>5}'.format(167) 会生成字符串 '00167'。如果您有带符号的数字,可以将 > 替换为 =,例如 '{:0=5}'.format(-167) 可以得到填充字符放置于符号和数字之间,即 '-0167' - HelloGoodbye

119
你可以在字符串上使用 ljust 方法。
>>> name = 'John'
>>> name.ljust(15)
'John           '

请注意,如果名称超过15个字符,则ljust不会截断它。如果您想最终得到恰好15个字符的字符串,可以对结果字符串进行切片:

>>> name.ljust(15)[:15]

2
我之前不知道这个,但是嘿,这也很酷。个人而言,我更喜欢使用 format 来进行所有字符串操作 :P +1 - Games Brainiac
这个答案也非常有帮助,我非常感激,谢谢。我相信它将来会很有用。 - user2977230
1
@amcgregor 速度并不是一切。有时候,你需要更多内置的灵活性,这正是.format()所提供的。 - Games Brainiac
供参考,对于这种用例,.ljust比.format快2倍以上: python -m timeit '"John".ljust(15)' 10000000次循环,5次中最好的结果:37.4纳秒每次循环 python -m timeit '"{:<15}".format("John")' 5000000次循环,5次中最好的结果:88.4纳秒每次循环 - undefined
1
你们为什么关心格式化字符串的速度?我觉得这种情况很不可能出现在一个热循环或类似的地方。 - undefined
显示剩余3条评论

36

如果您使用的是Python版本3.6或更高版本,您可以使用f字符串。

>>> string = "John"
>>> f"{string:<15}"
'John           '

或者如果您想把它放在左边

>>> f"{string:>15}"
'          John'

居中

>>> f"{string:^15}"
'     John      '

如需了解更多变量,请随时查看文档:https://docs.python.org/3/library/string.html#format-string-syntax


2
特别酷的是,您还可以轻松地插入之前计算过的长度:f"{string:<{calculated_length}}" - cherrywoods

13

您可以使用rjustljust函数在字符串前后添加特定字符以达到特定长度。

这些方法的第一个参数是转换字符串后的总字符数。

右对齐(向左添加)

numStr = '69' 
numStr = numStr.rjust(5, '*')

结果是***69

向左对齐(添加到右侧)

对于左侧:

numStr = '69' 
numStr = numStr.ljust(3, '#')

结果将会是69#

在前面填充零

另外,您可以使用以下方法添加零:

numstr.zfill(8)

这将给您 00000069 作为结果。


0
string = ""
name = raw_input() #The value at the field
length = input() #the length of the field
string += name
string += " "*(length-len(name)) # Add extra spaces

这将添加所需的空格数量,前提是字段长度>=提供的名称长度


与我在其他建议中添加的类似性能评论相同:您正在构造涉及多个字符串的多个副本。输入字符串,一个计算出的(无法内部化)可变长度字符串,然后是最终结果填充的字符串。而不是使用提供的 O(1) 工具来完成工作。链接 - amcgregor

0
name = "John" // your variable
result = (name+"               ")[:15] # this adds 15 spaces to the "name"
                                       # but cuts it at 15 characters

1
更好的方法:(name+" "*15)[:15] / 最佳方法:使用 ljust(),如Ismail所述。 - Pandu
你尝试过这段代码吗?如果尝试过,你会发现在Python中使用“//”会产生名称和/或语法错误。 - SethMMorton
@SethMMorton 对不起,我事后手动添加了//注释而没有进行测试。 - user2629998
@pandubear ljust()函数运作正常,但我们如何使填充的空格延伸至所需列? - Waseem Munir

0

通常我建议使用f-string/format版本,但有时您可能需要或想要使用printf风格的元组。这次我决定使用以下方式:

>>> res = (1280, 720)
>>> '%04sx%04s' % res
'1280x 720'

我认为这个版本比格式化的版本更易读:

>>> f'{res[0]:>4}x{res[1]:>4}'

0

我知道这是一个有点老的问题,但我最终自己制作了一个小类。

可能对某些人有用,所以我会把它放上去。我使用了一个类变量,它本质上是持久的,以确保添加足够的空格来清除任何旧行。请参见下面:

2021-03-02 更新:稍微改进了一下 - 当在大型代码库中工作时,您知道您正在编写的行是否是您关心的行,但您不知道之前已经写入控制台的内容以及您是否想要保留它。

此更新解决了这个问题,当您写入控制台时更新的类变量会跟踪您当前正在编写的行是否是您想要保留或允许稍后覆盖的行。

class consolePrinter():
'''
Class to write to the console

Objective is to make it easy to write to console, with user able to 
overwrite previous line (or not)
'''
# -------------------------------------------------------------------------    
#Class variables
stringLen = 0    
overwriteLine = False
# -------------------------------------------------------------------------    
    
# -------------------------------------------------------------------------
def writeline(stringIn, overwriteThisLine=False):
    import sys
    #Get length of stringIn and update stringLen if needed
    if len(stringIn) > consolePrinter.stringLen:
        consolePrinter.stringLen = len(stringIn)+1
    
    ctrlString = "{:<"+str(consolePrinter.stringLen)+"}"

    prevOverwriteLine = consolePrinter.overwriteLine
    if prevOverwriteLine:
        #Previous line entry can be overwritten, so do so
        sys.stdout.write("\r" + ctrlString.format(stringIn))
    else:
        #Previous line entry cannot be overwritten, take a new line
        sys.stdout.write("\n" + stringIn)
    sys.stdout.flush()
    
    #Update the class variable for prevOverwriteLine
    consolePrinter.overwriteLine = overwriteThisLine

    return

然后通过以下方式调用:

consolePrinter.writeline("text here", True) 

如果您想要使此行内容可以被覆盖,请使用以下代码:


consolePrinter.writeline("text here",False)

如果你不这样做。

请注意,为了使其正常工作,所有推送到控制台的消息都需要通过consolePrinter.writeline进行。


这不是答案,它回答了另一个问题。它也写得像Java。建议移动/删除。 - Gringo Suave

-1

我为我的问题刚刚编写了这个,它会添加空格,直到字符串的长度大于您给定的最小长度为止。

def format_string(str, min_length):
    while len(str) < min_length:
        str += " "
    return str

1
在Python中,字符串不是数组,它们是不可变对象。每次添加一个空格都会创建一个全新的字符串,该字符串是前一个字符串加上一个空格。然而,为了达到目标长度,需要多少次添加空格都是极其低效的解决方案。相比之下,使用实际提供的方法也作为答案给出,只会创建一个新的Python字符串对象。 - amcgregor

-1

首先检查字符串的长度是否需要缩短,然后添加空格,直到其与字段长度相同。

fieldLength = 15
string1 = string1[0:15] # If it needs to be shortened, shorten it
while len(string1) < fieldLength:
    rand += " "

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