如何在Python中打印“漂亮”字符串输出

时间:2021-02-27 21:45:40

I have a list of dicts with the fields classid, dept, coursenum, area, and title from a sql query. I would like to output the values in a human readable format. I was thinking a Column header at the top of each and then in each column the approrpiate output ie:

我有一个dicts列表,其中包含来自sql查询的字段classid,dept,coursenum,area和title。我想以人类可读的格式输出值。我在每个顶部想到一个Column标题,然后在每一列中考虑approrpiate输出,即:

CLASSID     DEPT     COURSE NUMBER        AREA     TITLE
foo         bar      foo                  bar      foo
yoo         hat      yoo                  bar      hat

(obviously with standard alignment/spacing)

(显然标准对齐/间距)

How would I accomplish this in python?

我如何在python中实现这一目标?

5 个解决方案

#1


55  

Standard Python string formatting may suffice.

标准Python字符串格式化可能就足够了。

# assume that your data rows are tuples
template = "{0:8}|{1:10}|{2:15}|{3:7}|{4:10}" # column widths: 8, 10, 15, 7, 10
print template.format("CLASSID", "DEPT", "COURSE NUMBER", "AREA", "TITLE") # header
for rec in your_data_source: 
  print template.format(*rec)

Or

# assume that your data rows are dicts
template = "{CLASSID:8}|{DEPT:10}|{C_NUM:15}|{AREA:7}|{TITLE:10}" # same, but named
print template.format( # header
  CLASSID="CLASSID", DEPT="DEPT", C_NUM="COURSE NUMBER", 
  AREA="AREA", TITLE="TITLE"
) 
for rec in your_data_source: 
  print template.format(**rec)

Play with alignment, padding, and exact format specifiers to get best results.

使用对齐,填充和精确格式说明符来获得最佳结果。

#2


11  

class TablePrinter(object):
    "Print a list of dicts as a table"
    def __init__(self, fmt, sep=' ', ul=None):
        """        
        @param fmt: list of tuple(heading, key, width)
                        heading: str, column label
                        key: dictionary key to value to print
                        width: int, column width in chars
        @param sep: string, separation between columns
        @param ul: string, character to underline column label, or None for no underlining
        """
        super(TablePrinter,self).__init__()
        self.fmt   = str(sep).join('{lb}{0}:{1}{rb}'.format(key, width, lb='{', rb='}') for heading,key,width in fmt)
        self.head  = {key:heading for heading,key,width in fmt}
        self.ul    = {key:str(ul)*width for heading,key,width in fmt} if ul else None
        self.width = {key:width for heading,key,width in fmt}

    def row(self, data):
        return self.fmt.format(**{ k:str(data.get(k,''))[:w] for k,w in self.width.iteritems() })

    def __call__(self, dataList):
        _r = self.row
        res = [_r(data) for data in dataList]
        res.insert(0, _r(self.head))
        if self.ul:
            res.insert(1, _r(self.ul))
        return '\n'.join(res)

and in use:

并在使用中:

data = [
    {'classid':'foo', 'dept':'bar', 'coursenum':'foo', 'area':'bar', 'title':'foo'},
    {'classid':'yoo', 'dept':'hat', 'coursenum':'yoo', 'area':'bar', 'title':'hat'},
    {'classid':'yoo'*9, 'dept':'hat'*9, 'coursenum':'yoo'*9, 'area':'bar'*9, 'title':'hathat'*9}
]

fmt = [
    ('ClassID',       'classid',   11),
    ('Dept',          'dept',       8),
    ('Course Number', 'coursenum', 20),
    ('Area',          'area',       8),
    ('Title',         'title',     30)
]

print( TablePrinter(fmt, ul='=')(data) )

produces

ClassID     Dept     Course Number        Area     Title                         
=========== ======== ==================== ======== ==============================
foo         bar      foo                  bar      foo                           
yoo         hat      yoo                  bar      hat                           
yooyooyooyo hathatha yooyooyooyooyooyooyo barbarba hathathathathathathathathathat

#3


4  

This function takes list comprehension to a bit of an extreme, but it accomplishes what you're looking for with optimal performance:

这个函数使列表理解有点极端,但它以最佳性能完成了你正在寻找的东西:

algorithm:

  1. find longest field in each column; i.e., 'max(map(len, column_vector))'
  2. 在每列中找到最长的字段;即'max(map(len,column_vector))'

  3. for each field (left to right, top to bottom), call str.ljust to align it to the left boundary of the column it belongs to.
  4. 对于每个字段(从左到右,从上到下),调用str.ljust将其对齐到它所属列的左边界。

  5. join fields with desired amount of separating whitespace (creating a row).
  6. 连接具有所需分隔空白量的字段(创建一行)。

  7. join collection of rows with a newline.
  8. 使用换行符连接行集合。

row_collection: list of iterables (dicts/sets/lists), each containing data for one row.

row_collection:iterables列表(dicts / sets / lists),每个包含一行的数据。

key_list: list that specifies what keys/indices to read from each row to form columns.

key_list:list,指定从每行读取哪些键/索引以形成列。

def getPrintTable(row_collection, key_list, field_sep=' '*4):
  return '\n'.join([field_sep.join([str(row[col]).ljust(width)
    for (col, width) in zip(key_list, [max(map(len, column_vector))
      for column_vector in [ [v[k]
        for v in row_collection if k in v]
          for k in key_list ]])])
            for row in row_collection])

#4


4  

You can simply left justify the string to a certain number of characters if you want to keep it simple:

如果你想保持简单,你可以简单地将字符串左对齐为一定数量的字符:

print string1.ljust(20) + string2.ljust(20)

#5


1  

You can try the Padnums module. The example output seems to match what you are requesting.

您可以尝试Padnums模块。示例输出似乎与您请求的内容相匹配。

Or this table indentation method.

或者这个表缩进方法。

I haven't used either, but they were in the first few result of googling "python pretty print table"

我没有使用过,但是他们在google搜索“python pretty print table”的前几个结果中

#1


55  

Standard Python string formatting may suffice.

标准Python字符串格式化可能就足够了。

# assume that your data rows are tuples
template = "{0:8}|{1:10}|{2:15}|{3:7}|{4:10}" # column widths: 8, 10, 15, 7, 10
print template.format("CLASSID", "DEPT", "COURSE NUMBER", "AREA", "TITLE") # header
for rec in your_data_source: 
  print template.format(*rec)

Or

# assume that your data rows are dicts
template = "{CLASSID:8}|{DEPT:10}|{C_NUM:15}|{AREA:7}|{TITLE:10}" # same, but named
print template.format( # header
  CLASSID="CLASSID", DEPT="DEPT", C_NUM="COURSE NUMBER", 
  AREA="AREA", TITLE="TITLE"
) 
for rec in your_data_source: 
  print template.format(**rec)

Play with alignment, padding, and exact format specifiers to get best results.

使用对齐,填充和精确格式说明符来获得最佳结果。

#2


11  

class TablePrinter(object):
    "Print a list of dicts as a table"
    def __init__(self, fmt, sep=' ', ul=None):
        """        
        @param fmt: list of tuple(heading, key, width)
                        heading: str, column label
                        key: dictionary key to value to print
                        width: int, column width in chars
        @param sep: string, separation between columns
        @param ul: string, character to underline column label, or None for no underlining
        """
        super(TablePrinter,self).__init__()
        self.fmt   = str(sep).join('{lb}{0}:{1}{rb}'.format(key, width, lb='{', rb='}') for heading,key,width in fmt)
        self.head  = {key:heading for heading,key,width in fmt}
        self.ul    = {key:str(ul)*width for heading,key,width in fmt} if ul else None
        self.width = {key:width for heading,key,width in fmt}

    def row(self, data):
        return self.fmt.format(**{ k:str(data.get(k,''))[:w] for k,w in self.width.iteritems() })

    def __call__(self, dataList):
        _r = self.row
        res = [_r(data) for data in dataList]
        res.insert(0, _r(self.head))
        if self.ul:
            res.insert(1, _r(self.ul))
        return '\n'.join(res)

and in use:

并在使用中:

data = [
    {'classid':'foo', 'dept':'bar', 'coursenum':'foo', 'area':'bar', 'title':'foo'},
    {'classid':'yoo', 'dept':'hat', 'coursenum':'yoo', 'area':'bar', 'title':'hat'},
    {'classid':'yoo'*9, 'dept':'hat'*9, 'coursenum':'yoo'*9, 'area':'bar'*9, 'title':'hathat'*9}
]

fmt = [
    ('ClassID',       'classid',   11),
    ('Dept',          'dept',       8),
    ('Course Number', 'coursenum', 20),
    ('Area',          'area',       8),
    ('Title',         'title',     30)
]

print( TablePrinter(fmt, ul='=')(data) )

produces

ClassID     Dept     Course Number        Area     Title                         
=========== ======== ==================== ======== ==============================
foo         bar      foo                  bar      foo                           
yoo         hat      yoo                  bar      hat                           
yooyooyooyo hathatha yooyooyooyooyooyooyo barbarba hathathathathathathathathathat

#3


4  

This function takes list comprehension to a bit of an extreme, but it accomplishes what you're looking for with optimal performance:

这个函数使列表理解有点极端,但它以最佳性能完成了你正在寻找的东西:

algorithm:

  1. find longest field in each column; i.e., 'max(map(len, column_vector))'
  2. 在每列中找到最长的字段;即'max(map(len,column_vector))'

  3. for each field (left to right, top to bottom), call str.ljust to align it to the left boundary of the column it belongs to.
  4. 对于每个字段(从左到右,从上到下),调用str.ljust将其对齐到它所属列的左边界。

  5. join fields with desired amount of separating whitespace (creating a row).
  6. 连接具有所需分隔空白量的字段(创建一行)。

  7. join collection of rows with a newline.
  8. 使用换行符连接行集合。

row_collection: list of iterables (dicts/sets/lists), each containing data for one row.

row_collection:iterables列表(dicts / sets / lists),每个包含一行的数据。

key_list: list that specifies what keys/indices to read from each row to form columns.

key_list:list,指定从每行读取哪些键/索引以形成列。

def getPrintTable(row_collection, key_list, field_sep=' '*4):
  return '\n'.join([field_sep.join([str(row[col]).ljust(width)
    for (col, width) in zip(key_list, [max(map(len, column_vector))
      for column_vector in [ [v[k]
        for v in row_collection if k in v]
          for k in key_list ]])])
            for row in row_collection])

#4


4  

You can simply left justify the string to a certain number of characters if you want to keep it simple:

如果你想保持简单,你可以简单地将字符串左对齐为一定数量的字符:

print string1.ljust(20) + string2.ljust(20)

#5


1  

You can try the Padnums module. The example output seems to match what you are requesting.

您可以尝试Padnums模块。示例输出似乎与您请求的内容相匹配。

Or this table indentation method.

或者这个表缩进方法。

I haven't used either, but they were in the first few result of googling "python pretty print table"

我没有使用过,但是他们在google搜索“python pretty print table”的前几个结果中