【问题标题】:Python tabulate - configure how to format cells containing listsPython制表 - 配置如何格式化包含列表的单元格
【发布时间】:2019-02-04 10:54:37
【问题描述】:

我正在使用 python-tabulate 打印具有包含列表的单元格的数据。 我可以自定义 python-tabulate 如何格式化单元格内容,从而以不同的方式格式化列表吗?

我希望避免手动预处理(将列表转换为字符串)传递给制表的数据。

如果制表不允许这样做,是否有其他库可以在其中定义更细粒度的格式选项?

示例代码:

from tabulate import tabulate

# Minimal sample. My output comes from an API and contains much more data
table = [['Sun', [1, 2, 3]], ['Moon', [4, 5, 6]]]
print(tabulate(table, tablefmt='plain', headers=['Planet', 'Value']))

输出:

Planet    Value
Sun       [1, 2, 3]
Moon      [4, 5, 6]

我希望输出的格式如何:

Planet    Value
Sun       1,2,3
Moon      4,5,6

【问题讨论】:

    标签: python tabulate


    【解决方案1】:

    我建议你尝试不同的库。我检查了 DOC 并没有发现任何相关内容。

    或者有它的功能(虽然你没有要求)

    from tabulate import tabulate
    
    def delist(lst):
        return ",".join([str(item) for item in lst]) 
    
    table = [['Sun', delist([1, 2, 3])], ['Moon', delist([4, 5, 6])]]
    print(tabulate(table, tablefmt='plain', headers=['Planet', 'Value']))
    >>>
    Planet    Value
    Sun       1,2,3
    Moon      4,5,6
    

    最后一个选项,也许有点绝望……是采取制表类并将此功能集成到其中。但是有点矫枉过正

    【讨论】:

      【解决方案2】:

      由于我找不到相应配置制表的方法,因此一种解决方案是猴子补丁制表内部 _format 方法。

      原始方法(表 0.8.2):

      def _format(val, valtype, floatfmt, missingval="", has_invisible=True):
          """Format a value accoding to its type.
      
          Unicode is supported:
      
          >>> hrow = ['\u0431\u0443\u043a\u0432\u0430', '\u0446\u0438\u0444\u0440\u0430'] ; \
              tbl = [['\u0430\u0437', 2], ['\u0431\u0443\u043a\u0438', 4]] ; \
              good_result = '\\u0431\\u0443\\u043a\\u0432\\u0430      \\u0446\\u0438\\u0444\\u0440\\u0430\\n-------  -------\\n\\u0430\\u0437             2\\n\\u0431\\u0443\\u043a\\u0438           4' ; \
              tabulate(tbl, headers=hrow) == good_result
          True
      
          """
          if val is None:
              return missingval
      
          if valtype in [int, _text_type]:
              return "{0}".format(val)
          elif valtype is _binary_type:
              try:
                  return _text_type(val, "ascii")
              except TypeError:
                  return _text_type(val)
          elif valtype is float:
              is_a_colored_number = has_invisible and isinstance(val, (_text_type, _binary_type))
              if is_a_colored_number:
                  raw_val = _strip_invisible(val)
                  formatted_val = format(float(raw_val), floatfmt)
                  return val.replace(raw_val, formatted_val)
              else:
                  return format(float(val), floatfmt)
          else:
              return "{0}".format(val)
      

      我的修改版:

      # tabulate_extensions.py
      from tabulate import _text_type, _binary_type, _strip_invisible
      
      
      def _format_extended(val, valtype, floatfmt, missingval="", has_invisible=True):
          """Format a value accoding to its type.
      
          Unicode is supported:
      
          >>> hrow = ['\u0431\u0443\u043a\u0432\u0430', '\u0446\u0438\u0444\u0440\u0430'] ; \
              tbl = [['\u0430\u0437', 2], ['\u0431\u0443\u043a\u0438', 4]] ; \
              good_result = '\\u0431\\u0443\\u043a\\u0432\\u0430      \\u0446\\u0438\\u0444\\u0440\\u0430\\n-------  -------\\n\\u0430\\u0437             2\\n\\u0431\\u0443\\u043a\\u0438           4' ; \
              tabulate(tbl, headers=hrow) == good_result
          True
      
          """
          if val is None:
              return missingval
      
          if valtype in [int, _text_type]:
              # Change list formatting [1,2,3] -> 1,2,3
              if type(val) == list:
                  val = ','.join([str(x) for x in val])
              return "{0}".format(val)
          elif valtype is _binary_type:
              try:
                  return _text_type(val, "ascii")
              except TypeError:
                  return _text_type(val)
          elif valtype is float:
              is_a_colored_number = has_invisible and isinstance(val, (_text_type, _binary_type))
              if is_a_colored_number:
                  raw_val = _strip_invisible(val)
                  formatted_val = format(float(raw_val), floatfmt)
                  return val.replace(raw_val, formatted_val)
              else:
                  return format(float(val), floatfmt)
          else:
              return "{0}".format(val)
      

      在我的代码中,我将表格内部方法替换为我的,如下所示:

      from mypkg.tabulate_extensions import _format_extended
      
      tabulate._format = _format_extended
      

      现在的输出如您所愿。 好消息是我现在可以以任何我想要的方式扩展其他单元格类型(如字典)的格式。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-13
        相关资源
        最近更新 更多