【问题标题】:Creating a formatted table from a list of tuples从元组列表创建格式化表
【发布时间】:2023-03-12 04:31:02
【问题描述】:

我有一个看起来像这样的数据列表:

[
    (
        1,
        u'python -c \'print("ok")\'',
        u'data',
        u'python'
    ), (
        2,
        u'python -c \'print("this is some data")\'',
        u'data',
        u'python'
    )
]

此数据从数据库中取出并显示为此,并且不断增长。我想做的是像这样显示数据:

Language  |  Type  |   Payload
-------------------------------
 python   |  data  |  python -c 'print("ok")'
 python   |  data  |  python -c 'print("this is some data")'

我有一个功能可以做同样的事情,但并不完全符合预期:

def print_table(data, cols, width):
    n, r = divmod(len(data), cols)
    pattern = "{{:{}}}".format(width)
    line = "\n".join(pattern * cols for _ in range(n))
    last_line = pattern * r
    print(line.format(*data))
    print(last_line.format(*data[n*cols]))

如何使我的数据输出看起来符合要求?从答案来看,pandas 是可能的,但我也想要一种不安装外部模块的方法

【问题讨论】:

    标签: python python-2.7 formatting format


    【解决方案1】:

    处理任意数量列的解决方案:

    from operator import itemgetter
    
    data = [
        ('ID', 'Payload', 'Type', 'Language'),
        (1, u'python -c \'print("ok")\'', u'data', u'python'),
        (2, u'python -c \'print("this is some data")\'', u'data', u'python')
    ]
    
    
    def print_table(data):
        lengths = [
            [len(str(x)) for x in row]
            for row in data
        ]
    
        max_lengths = [
            max(map(itemgetter(x), lengths))
            for x in range(0, len(data[0]))
        ]
    
        format_str = ''.join(map(lambda x: '%%-%ss | ' % x, max_lengths))
    
        print(format_str % data[0])
        print('-' * (sum(max_lengths) + len(max_lengths) * 3 - 1))
    
        for x in data[1:]:
            print(format_str % x)
    
    print_table(data)
    

    输出:

    $ python table.py
    ID | Payload                                | Type | Language |
    ---------------------------------------------------------------
    1  | python -c 'print("ok")'                | data | python   |
    2  | python -c 'print("this is some data")' | data | python   |
    

    【讨论】:

      【解决方案2】:

      分析数据的最大宽度并使用字符串格式 - 稍后一些“创造性”格式:

      data = [
          (
              1,
              u'python -c \'print("ok")\'',
              u'data',
              u'python'
          ), (
              2,
              u'python -c \'print("this is some data")\'',
              u'data',
              u'python'
          )
      ]
      
      
      
      def print_table(data):
          widths = {0:0, 3:len("Language"),2:len("Type"),1:len("Payload")}
          for k in data:
              for i,d in enumerate(k): 
                  widths[i] = max(widths[i],len(str(d))) 
          # print(widths)
      
          lan, typ, pay = ["Language","Type","Payload"]
          print(f"{lan:<{widths[3]}}  |  {typ:<{widths[2]}}  |  {pay:<{widths[1]}}")
          # adjust by 10 for '  |  ' twice
          print("-" * (widths[1]+widths[2]+widths[3]+10)) 
          for k in data:
              _, pay, typ, lan = k
              print(f"{lan:<{widths[3]}}  |  {typ:<{widths[2]}}  |  {pay:<{widths[1]}}") 
      

      输出:

      Language  |  Type  |  Payload                               
      ------------------------------------------------------------
      python    |  data  |  python -c 'print("ok")'               
      python    |  data  |  python -c 'print("this is some data")'
      

      等效的 Python 2.7 代码:

      # w == widths - would break 79 chars/line else wise
      def print_table(data):
          w = {0:0, 3:len("Language"),2:len("Type"),1:len("Payload")}
          for k in data:
              for i,d in enumerate(k): 
                  w[i] = max(w[i],len(str(d))) 
      
      
          lan, typ, pay = ["Language","Type","Payload"]
          print "{:<{}}  |  {:<{}}  |  {:<{}}".format(lan, w[3], typ, w[2], pay, w[1])   
          print "-" * (w[1]+w[2]+w[3]+10) 
          for k in data:
              _, pay, typ, lan = k
              print "{:<{}}  |  {:<{}}  |  {:<{}}".format(lan, w[3], typ, w[2], pay, w[1]) 
      

      【讨论】:

      • 有没有办法做到这一点并与 2.x 和 3+ 兼容? 2.x 不支持f""
      • @13aal 您可以将f'strings' 转换为普通的.format() 语法-见编辑-抱歉没有看到python 2.7标签-python2虽然不使用print()作为函数-所以它不是以这种方式兼容 - 您可能希望从未来导入打印:how-to-use-from-future-import-print-function
      【解决方案3】:

      您可以为此使用pandas

      import pandas as pd
      data = pd.DataFrame(a, columns=['id','Payload', 'type', 'Language'])
      print(data)
      

      给你:

         id                                 Payload  type Language
      0   1                 python -c 'print("ok")'  data   python
      1   2  python -c 'print("this is some data")'  data   python
      

      【讨论】:

      • 有没有办法在不安装另一个库的情况下做到这一点?
      • 对不起,我应该这么说
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-15
      • 1970-01-01
      • 2022-12-08
      • 2010-10-21
      • 2017-03-21
      相关资源
      最近更新 更多