python字符串格式化列

时间:2013-09-30 20:18:03

标签: python

我正在尝试格式化字符串,以便在两者之间排列一切。

APPLES                           $.99                           214                       
kiwi                             $1.09                           755 

我正在尝试这样做:

fmt = ('{0:30}{1:30}{2:30}'.format(Fruit,price,qty))

如何排列专栏?我阅读了文档,但我很困惑。我以为{1:30}会使它成为30个空格,然后它会打印下一个项目,但它看起来是前一个项目结束的30个空格。

由于

4 个答案:

答案 0 :(得分:35)

str.format()使您的字段在可用空间内保持对齐。使用alignment specifiers更改对齐方式:

  

'<'强制字段在可用空间内左对齐(这是大多数对象的默认值)。

     

'>'强制字段在字段内右对齐   可用空间(这是数字的默认值)。

     

'='强制填充后放置   签名(如果有的话)但在数字之前。这用于打印字段   形式为'+000000120'。此对齐选项仅对有效   数字类型。

     

'^'强制字段居中   可用空间。

这是一个示例(左对齐和右对齐):

>>> for args in (('apple', '$1.09', '80'), ('truffle', '$58.01', '2')):
...     print '{0:<10} {1:>8} {2:>8}'.format(*args)
...
apple         $1.09       80
truffle      $58.01        2

答案 1 :(得分:0)

直到现在,我才意识到Python拥有格式化列的解决方案-我决定研究它,以防万一,因为我已经为另一种没有内置解决方案的语言创建了自己的解决方案( Lua),并且由于Logic是通用的,因此我通过几次按键将其移植到Python。

了解Python有其自己的解决方案,我将考虑将其集成到当前解决方案中。

但是,当我创建替代解决方案时,我将继续在此处发布解决方案,以便您可以看到我的解决方案对用户的友好程度-我对Python的抱怨之一是某些格式不直观,例如False,True的三元运算符(老实说,True,False最好是先声明后再进行排序),而其他运算符则很奇怪……

该示例函数显示了正在使用的截断(注意:不必要的逻辑开销,仍在移动-例如if _truncate ...等。)还显示了格式列系统...

这是非常基本的-将制表符转换为空格,计算列的长度,如果太多则添加空格-如果文本太多则将其切碎(我的另一种解决方案有一个可以使用的缓冲区,也可以使用border以便边框字符出现,并在列之间强制使用最少1个空白字符-我还没有机会在Python变体中添加它),等等。

调试和输出非常棒。

有几个主要功能... String.FormatColumn([_width,_text],...),String.FormatSimpleColumn(_width,[_text,...]和String.FormatColumnEx(_empty_chars,[_width, _text],...)..

String.FormatSimpleColumn使用一次宽度,并将其用于所有列,仅重复文本。.

String.FormatColumn采用每一列的宽度和文本...

String.FormatColumnEx与FormatColumn相同,除了它允许您指定要使用的字符而不是空格-我通常为索引行使用小数或其他字符。...

对于我的Lua实现,我还可以选择修剪合适的空格,但是最终只使用了辅助函数来修剪不需要的空格...我离开了它们,因为如果您设置了列,则可以只需在函数调用之外的字符串中添加一些内容即可,并且修整很简单。这也意味着您可以简单地将函数调用链接为完全相同的结果,而不是链接参数...以最适合的方式你..

##
## Sandbox - All Works, if public, are released under the ACL or Acecool Company License - Josh 'Acecool' Moser
##


##
## Declarations for Globals, CONSTants, ENUMeration, etc..
##

## Define the tab width in terms of how many space-chars are used per tab character - Pi uses 8, Windows uses 4, some use 2, etc..
CONST_TAB_WIDTH                             = 4


##
## String Library - This library only includes Format Column debugging output format system..
##
class String:


    ##
    ##
    ##
    def FormatColumnStripR( _width = 25, _text ='', *_varargs ):
        return String.FormatColumn( _width, _text, *_varargs ).rstrip( )


    ##
    ##
    ##
    def FormatSimpleColumnStripR( _width = 25, *_varargs ):
        return String.FormatSimpleColumn( _width, *_varargs ).rstrip( )


    ##
    ## Helper function which lets you define width for each text, and it repeats it for you so you can repeat text and all columns will be the same width
    ##
    ## Purpose:
    ##          The purpose of the Format Column Helpers is to improve data output, primarily for debugging so output is easier to follow..
    ## Usage:
    ##      String.FormatColumn( 25, 'Text / Key', 15, 'Some Value', 15, 'Another Key', 50, 'Another Value' )
    ##      String.FormatColumn( 25, 'Text / Key', 15, 'Some Value', 15, 'Another Key', 50, 'Another Value' )
    ##      String.FormatColumn( 25, 'Key', 15, 'Some', 15, 'Another', 50, 'Value' )
    ##
    ## Output:
    ##      Text / Key               Some Value     Another Key    Another Value                                     <LINE END>
    ##      Text / Key               Some Value     Another Key    Another Value                                     <LINE END>
    ##      Key                      Some           Another        Value                                             <LINE END>
    ##
    def FormatColumn( _width = 25, _text = '', *_varargs ):
        return String.FormatColumnEx( ' ', _width, _text, *_varargs )


    ##
    ## Helper function which lets you define width for each text, and it repeats it for you so you can repeat text and all columns will be the same width
    ##
    ## Purpose:
    ##          The purpose of the Format Column Helpers is to improve data output, primarily for debugging so output is easier to follow..
    ## Usage:
    ##      String.FormatColumnEx( '.', 25, 'Text / Key', 15, 'Some Value', 15, 'Another Key', 50, 'Another Value' )
    ##      String.FormatColumnEx( ' ', 25, 'Text / Key', 15, 'Some Value', 15, 'Another Key', 50, 'Another Value' )
    ##      String.FormatColumnEx( ' ', 25, 'Key', 15, 'Some', 15, 'Another', 50, 'Value' )
    ##
    ## Output:
    ##      Text / Key...............Some Value.....Another Key....Another Value.....................................<LINE END>
    ##      Text / Key               Some Value     Another Key    Another Value                                     <LINE END>
    ##      Key                      Some           Another        Value                                             <LINE END>
    ##
    def FormatColumnEx( _empty_char = ' ', _width = 25, _text = '', *_varargs ):
        ## Make sure our text is a string
        _text = str( _text )

        ## For each tab used, calculate how many spaces should be used with minimum of 1 and maximum of 4 being the range depending which snap-point is used.. Then strip that tab and add spaces in its place..
        _text = _text.expandtabs( CONST_TAB_WIDTH )

        ## Count how many additional arguments we have
        _count = len( _varargs )

        ## Since our Ex function, this, must use a paired-system, we make sure the rounded division is > 0
        _more = ( round( _count / 2, 0 ) > 0 )

        ## How many repeating chars do we need to create?
        _reps = ( _width - len( _text ) )

        ## Build a string to fill the empty column space with spaces so everything lines up - as long as the right font is used ( where all chars are the same size )
        _empty = _empty_char * _reps

        ## Now we ensure our text is limited to the _width size - data going over is truncated...TernaryFunc( _reps > 0, _empty, _empty )
        ## _data = String.SubStr( _text + ( _empty ), 0, _width )
        ## _data = ( _text + ( _empty ) )[  : _width ]
        _data = String.Truncate( _text + ( _empty ), _width )

        ## If we have more cars
        if ( _more ):
            ## Recursive call by shifting our VarArgs left so they populate _width and _text - then add the result to the data var... This only stops when no more paired options are left...
            _data = _data + String.FormatColumnEx( _empty_char, *_varargs )

        ## Return the data..
        return _data


    ##
    ## Helper function which lets you define width once, and it repeats it for you so you can repeat text and all columns will be the same width
    ##
    ## Purpose:
    ##          The purpose of the Format Column Helpers is to improve data output, primarily for debugging so output is easier to follow..
    ## Usage:
    ##      String.FormatSimpleColumn( 15, 'Text / Key', 'Some Value', 'Another Key', 'Another Value' )
    ##      String.FormatSimpleColumn( 15, 'Key', 'Some', 'Another', 'Value' )
    ##
    ## Output:
    ##      Text / Key     Some Value     Another Key    Another Value  <LINE END>
    ##      Key            Some           Another        Value          <LINE END>
    ##
    def FormatSimpleColumn( _width = 25, *_varargs ):
        ## Count how many text elements we have...
        _count = len( _varargs )

        ## Set up our return var
        _data = ''

        ## If we have at least 1 text element to set-up into a column
        if ( _count > 0 ):
            ## Then we loop through each vararg
            for _text in _varargs:
                ## If width is negative, use the length of the string plus the absolute value of width as a buffer...
                if ( _width < 0 ):
                    _data = _data + String.FormatColumn( len( str( _text ) ) + abs( _width ), str( _text ) )
                else:
                    ## And we use a pseudo recursive call on the FormatColumnEx function - extra args...
                    _data = _data + String.FormatColumn( _width, str( _text ) )

        ## Return the data..
        return _data


    ##
    ## SubString replacement
    ##
    ## Usage:
    ##      _data = String.SubStr( _text, 0, 10 )
    ##
    def SubStr( _text, _start, _end ):
        return _text[ _start : _end ]


    ##
    ## Truncate characters of a string after _len'nth char, if necessary... If _len is less than 0, don't truncate anything... Note: If you attach a suffix, and you enable absolute max length then the suffix length is subtracted from max length... Note: If the suffix length is longer than the output then no suffix is used...
    ##
    ## Usage: Where _text = 'Testing', _width = 4
    ##      _data = String.Truncate( _text, _width )                        == Test
    ##      _data = String.Truncate( _text, _width, '..', True )            == Te..
    ##
    ## Equivalent Alternates: Where _text = 'Testing', _width = 4
    ##      _data = String.SubStr( _text, 0, _width )                       == Test
    ##      _data = _text[  : _width ]                                      == Test
    ##      _data = ( _text )[  : _width ]                                  == Test
    ##
    def Truncate( _text, _max_len = -1, _suffix = False, _absolute_max_len = True ):
        ## Length of the string we are considering for truncation
        _len            = len( _text )

        ## Whether or not we have to truncate
        _truncate       = ( False, True )[ _len > _max_len ]

        ## Note: If we don't need to truncate, there's no point in proceeding...
        if ( not _truncate ):
            return _text

        ## The suffix in string form
        _suffix_str     = ( '',  str( _suffix ) )[ _truncate and _suffix != False ]

        ## The suffix length
        _len_suffix     = len( _suffix_str )

        ## Whether or not we add the suffix
        _add_suffix     = ( False, True )[ _truncate and _suffix != False and _max_len > _len_suffix ]

        ## Suffix Offset
        _suffix_offset = _max_len - _len_suffix
        _suffix_offset  = ( _max_len, _suffix_offset )[ _add_suffix and _absolute_max_len != False and _suffix_offset > 0 ]

        ## The truncate point.... If not necessary, then length of string.. If necessary then the max length with or without subtracting the suffix length... Note: It may be easier ( less logic cost ) to simply add the suffix to the calculated point, then truncate - if point is negative then the suffix will be destroyed anyway.
        ## If we don't need to truncate, then the length is the length of the string.. If we do need to truncate, then the length depends on whether we add the suffix and offset the length of the suffix or not...
        _len_truncate   = ( _len, _max_len )[ _truncate ]
        _len_truncate   = ( _len_truncate, _max_len )[ _len_truncate <= _max_len ]

        ## If we add the suffix, add it... Suffix won't be added if the suffix is the same length as the text being output...
        if ( _add_suffix ):
            _text = _text[ 0 : _suffix_offset ] + _suffix_str + _text[ _suffix_offset: ]

        ## Return the text after truncating...
        return _text[ : _len_truncate ]


    ##
    ##
    ##
    def __example__( self ):
        ##
        ## Truncate Example...
        ##
        _col_key    = 20
        _col_eq     = 10
        _col_res    = 15
        _row_eq     = '=='
        _text       = 'Testing'
        print( '--------------------------------------------- 8' )
        _width = 8
        print( String.FormatColumn( _col_key, 'Testing',        _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width ) ) )
        print( String.FormatColumn( _col_key, 'Testing',        _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width, '..', True ) ) )
        print( '--------------------------------------------- 7' )
        _width = 7
        print( String.FormatColumn( _col_key, 'Testing',        _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width ) ) )
        print( String.FormatColumn( _col_key, 'Testing',        _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width, '..', True ) ) )
        print( '--------------------------------------------- 6' )
        _width = 6
        print( String.FormatColumn( _col_key, 'Testin',         _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width ) ) )
        print( String.FormatColumn( _col_key, 'Test..',         _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width, '..', True ) ) )
        print( '--------------------------------------------- 5' )
        _width = 5
        print( String.FormatColumn( _col_key, 'Testi',          _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width ) ) )
        print( String.FormatColumn( _col_key, 'Tes..',          _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width, '..', True ) ) )
        print( '--------------------------------------------- 4' )
        _width = 4
        print( String.FormatColumn( _col_key, 'Test',           _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width ) ) )
        print( String.FormatColumn( _col_key, 'Te..',           _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width, '..', True ) ) )
        print( '--------------------------------------------- 3' )
        _width = 3
        print( String.FormatColumn( _col_key, 'Tes',            _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width ) ) )
        print( String.FormatColumn( _col_key, 'T..',            _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width, '..', True ) ) )
        print( '--------------------------------------------- 2' )
        _width = 2
        print( String.FormatColumn( _col_key, 'Te',             _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width ) ) )
        print( String.FormatColumn( _col_key, '..',             _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width, '..', True ) ) )
        print( '--------------------------------------------- 1' )
        _width = 1
        print( String.FormatColumn( _col_key, 'T',              _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width ) ) )
        print( String.FormatColumn( _col_key, '.',              _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width, '..', True ) ) )
        print( '--------------------------------------------- 0' )
        _width = 0
        print( String.FormatColumn( _col_key, '',               _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width ) ) )
        print( String.FormatColumn( _col_key, '',               _col_eq, _row_eq,           _col_res, String.Truncate( _text, _width, '..', True ) ) )
        print( '---------------------------------------------' )

答案 2 :(得分:0)

我认为更好的方法是根据其内容自动调整列宽

rows = [('apple', '$1.09', '80'), ('truffle', '$58.01', '2')]

lens = []
for col in zip(*rows):
    lens.append(max([len(v) for v in col]))
format = "  ".join(["{:<" + str(l) + "}" for l in lens])
for row in rows:
    print(format.format(*row))

输出:

apple    $1.09   80
truffle  $58.01  2 

演示:https://code.sololearn.com/cttJgVTx55bm/#py

答案 3 :(得分:0)

使用python3 f字符串(不是您的示例,而是我的):

alist = ["psi", "phi", "omg", "chi1", "chi2", "chi3", "chi4", "chi5", "tau"]
for ar in alist:
    print(f"{ar: >8}", end=" ")
print()
for ar in alist:
    ang = ric.get_angle(ar)
    print(f"{ang:8.4}", end=" ")
print()

生成

  psi      phi      omg     chi1     chi2     chi3     chi4     chi5      tau 
4.574   -85.28    178.1   -62.86   -65.01   -177.0    80.83    8.611    115.3