python字符串格式化列中的行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19103052/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
python string formatting Columns in line
提问by Trying_hard
I am trying to format the string so everything lines up between the two.
我正在尝试格式化字符串,以便在两者之间排列所有内容。
APPLES $.99 214
kiwi .09 755
I am trying this by doing:
我正在尝试这样做:
fmt = ('{0:30}{1:30}{2:30}'.format(Fruit,price,qty))
How would I get a column to line up? I read the docs but I am confused. I was thinking that the {1:30}
would make it 30 spaces, then it would print the next item, but it appears that it is 30 spaces from where the previous item ended.
我如何让一列排队?我阅读了文档,但我很困惑。我在想这{1:30}
会使它有 30 个空格,然后它会打印下一个项目,但它似乎与前一个项目结束的地方相距 30 个空格。
Thanks
谢谢
采纳答案by Steven Rumbalski
str.format()
is making your fields left aligned within the available space. Use alignment specifiersto change the alignment:
str.format()
使您的字段在可用空间内左对齐。使用对齐说明符更改对齐方式:
'<'
Forces the field to be left-aligned within the available space (this is the default for most objects).
'>'
Forces the field to be right-aligned within the available space (this is the default for numbers).
'='
Forces the padding to be placed after the sign (if any) but before the digits. This is used for printing fields in the form ‘+000000120'. This alignment option is only valid for numeric types.
'^'
Forces the field to be centered within the available space.
'<'
强制字段在可用空间内左对齐(这是大多数对象的默认设置)。
'>'
强制字段在可用空间内右对齐(这是数字的默认值)。
'='
强制将填充放置在符号(如果有)之后但在数字之前。这用于以“+000000120”形式打印字段。此对齐选项仅对数字类型有效。
'^'
强制字段在可用空间内居中。
Here's an example (with both left and right alignments):
这是一个示例(具有左对齐和右对齐):
>>> for args in (('apple', '.09', '80'), ('truffle', '.01', '2')):
... print '{0:<10} {1:>8} {2:>8}'.format(*args)
...
apple .09 80
truffle .01 2
回答by Acecool
I wasn't aware Python has a solution for formatting columns until now - I decided to look into it just in case it did as I already created my own solution for another language which doesn't have a built-in solution ( Lua ) and as Logic is Universal, I ported it to Python in a few key-strokes.
直到现在我才知道 Python 有格式化列的解决方案 - 我决定研究它,以防万一,因为我已经为另一种没有内置解决方案( Lua )的语言创建了自己的解决方案,并且由于 Logic 是通用的,因此我通过几次按键将其移植到 Python。
Knowing Python has its own solution, I'll be looking into integrating it into my current solution.
知道 Python 有自己的解决方案,我将考虑将它集成到我当前的解决方案中。
However, as I created an alternate solution, I'll go ahead and post my solution here so you can see how user-friendly my solution - one of my complaints with Python is some of the formatting is less than intuitive such as the Ternary Operator of False, True ( Honestly, True, False would be better order along with having the statement first ), and others are just strange...
但是,当我创建了一个替代解决方案时,我将继续在这里发布我的解决方案,以便您可以看到我的解决方案是多么用户友好 - 我对 Python 的抱怨之一是某些格式不太直观,例如三元运算符的假,真(老实说,真,假会更好的顺序以及首先声明),而其他人只是奇怪......
The example function shows Truncate in use ( note: some logic costs aren't necessary, still moving things around - for instance the if _truncate ... etc.. ) also showing the format column system...
示例函数显示 Truncate 正在使用中(注意:一些逻辑成本不是必需的,仍在移动 - 例如 if _truncate ... 等)还显示了格式列系统...
It's pretty basic - convert tabs to spaces, count the length of columns, add spaces if there are too many - if there is too much text then chop it ( my other solution has a buffer you can use or border so border chars show up, and to force 1 blank char minimum between columns - I haven't had a chance to add it in the Python variant yet ), etc...
这是非常基本的 - 将制表符转换为空格,计算列的长度,如果太多就添加空格 - 如果文本太多,然后将其切碎(我的另一个解决方案有一个可以使用的缓冲区或边框,以便显示边框字符,并在列之间强制最少 1 个空白字符 - 我还没有机会将它添加到 Python 变体中),等等......
It is fantastic for debugging, and output..
它非常适合调试和输出..
There are several main functions... String.FormatColumn( [ _width, _text ], ... ), String.FormatSimpleColumn( _width, [ _text, ... ], and String.FormatColumnEx( _empty_chars, [ _width, _text ], ... )..
主要有几个函数... String.FormatColumn( [ _width, _text ], ... ), String.FormatSimpleColumn( _width, [ _text, ... ], and String.FormatColumnEx( _empty_chars, [ _width, _text ], ……)。
String.FormatSimpleColumn takes width once, and uses that for all columns, repeat text only..
String.FormatSimpleColumn 使用一次宽度,并将其用于所有列,仅重复文本..
String.FormatColumn takes width and text for every column...
String.FormatColumn 为每列获取宽度和文本...
String.FormatColumnEx is the same as FormatColumn except it lets you specify the characters to use instead of spaces - I typically use decimals or another char for the index row....
String.FormatColumnEx 与 FormatColumn 相同,除了它允许您指定要使用的字符而不是空格 - 我通常使用小数或其他字符作为索引行......
for my Lua implementation, I also had the option to trim the right spaces but ended up just using a helper function to trim if the spaces aren't wanted... I leave them because if you set up columns, you can simply append something to the string outside of the function call if you wanted to... and trimming is simple.. It also means you can simply chain the function calls for the exact same result instead of chaining arguments... whichever looks best for you..
对于我的 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( '---------------------------------------------' )
回答by codeskyblue
I think the better way is auto adjust the column width from its content
我认为更好的方法是从其内容中自动调整列宽
rows = [('apple', '.09', '80'), ('truffle', '.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))
Output:
输出:
apple .09 80
truffle .01 2