【问题标题】:Easiest way to turn a list into an HTML table in python?在 python 中将列表转换为 HTML 表格的最简单方法?
【发布时间】:2010-12-01 07:12:15
【问题描述】:

假设我有一个这样的列表:

['one','two','three','four','five','six','seven','eight','nine']

我想尝试将这些数据转换为各种尺寸的 HTML 表格:

one     two    three
four    five   six
seven   eight  nine

one    four   seven
two    five   eight
three  six    nine

one    two   three  four
five   six   seven  eight
nine

是否有一个库可以处理这个问题而无需进行疯狂的列表拼接或嵌套 for 循环?我的 google 搜索显示有一些 HTML 库,但我没有时间逐个查看它们是否可以很好地处理表格。有没有人不得不这样做?如果有,你是怎么做到的?

【问题讨论】:

    标签: python html-table html-generation


    【解决方案1】:

    我会将您的问题分解为两部分:

    • 给定一个“平面列表”,生成一个子列表列表,其中子列表具有给定长度,并且整个列表可以按“行专业”顺序(您的第一个和第三个示例)或“列专业” (你的第二个例子);
    • 给定一个包含字符串项的子列表,从中生成一个 HTML 表格。

    我认为这两个任务非常不同,将它们混合起来并没有什么好处(也没有什么可失去的),所以如果有任何设计良好的库进行这种混合,我会感到惊讶。

    对于第 1 点,row-major 很简单:

    def row_major(alist, sublen):      
      return [alist[i:i+sublen] for i in range(0, len(alist), sublen)]
    

    而且专栏主要不是那么糟糕:

    def col_major(alist, sublen):
      numrows = (len(alist)+sublen-1) // sublen 
      return [alist[i::sublen] for i in range(numrows)]
    

    例如...:

    L = ['one','two','three','four','five','six','seven','eight','nine']
    for r in row_major(L, 3): print r
    print
    for r in col_major(L, 3): print r
    for r in row_major(L, 4): print r
    

    产生您想要的三个结果(每行一个列表,还不是 HTML 形式;-)。

    问题的后半部分——从字符串列表生成一个 HTML 表格:

    def html_table(lol):
      print '<table>'
      for sublist in lol:
        print '  <tr><td>'
        print '    </td><td>'.join(sublist)
        print '  </td></tr>'
      print '</table>'
    

    如果您想将其作为单个字符串而不是打印出来,请将每个 print 更改为 yield 并使用 '\n'.join(html_table(lol))

    现在您有了两个简单、有用、可用和可重用的构建块——只要您想将数据呈现为 HTML 表格以外的任何内容,以及要呈现的列表列表时,将它们分开就会派上用场因为 HTML 表格来自任何其他构建方式。在您的应用程序代码中将它们放在一起很容易,但当然也很容易做一个简单的“粘合例程”,例如,假设基于yieldhtml_table 版本并且需要单个字符串结果:

    def list_to_html_table(alist, sublength, column_major=False):
      if column_major:
        lol = col_major(alist, sublength)
      else:
        lol = row_major(alist, sublength)
      return ''.join(html_table(lol))
    

    这种构建块方法不是真的比使用大块的糊状胶水编程更好、更愉快、更有效率吗...?-)

    【讨论】:

    • 您能否展示如何使用 yield 来处理 list of list 字符串,例如 [['e1','f1 '],['e2','f2']]。你需要退货。
    【解决方案2】:

    使用tabulate

    from tabulate import tabulate
    
    table = [['one','two','three'],['four','five','six'],['seven','eight','nine']]
    
    print(tabulate(table, tablefmt='html'))
    

    这会产生以下输出。

    <table>
    <tbody>
    <tr><td>one  </td><td>two  </td><td>three</td></tr>
    <tr><td>four </td><td>five </td><td>six  </td></tr>
    <tr><td>seven</td><td>eight</td><td>nine </td></tr>
    </tbody>
    </table>
    

    【讨论】:

    • nice.. 我添加了 prettytable 作为另一个选项。
    • 最简单、最少的代码行。这应该是最好的答案
    • 太棒了!伟大的项目
    【解决方案3】:

    为了将来参考,我实现了一个名为 simpletable 的小型 Python 模块来提供简单的 HTML 表格生成。它也处理这个问题中描述的问题。

    用法简单如下:

    import simpletable
    
    test_data = [str(x) for x in range(20)]
    formatted_data = simpletable.fit_data_to_columns(test_data, 5)
    table = simpletable.SimpleTable(formatted_data)
    html_page = simpletable.HTMLPage(table)
    html_page.save("test_page.html")
    

    由于它不需要第三方包,您可以从my repository 获取代码并在您的项目中使用它。

    【讨论】:

      【解决方案4】:

      另一种选择是漂亮的:

      from prettytable import PrettyTable
      pt = PrettyTable()
      

      如果要生成html格式:

      print(pt.get_html_string())
      

      如果只生成ascii格式表:

      print(pt.get_string())
      

      更多选项请参考官方文档:https://ptable.readthedocs.io/en/latest/tutorial.html,例如启用不同的样式。

      享受吧。

      【讨论】:

      • 正是我想要的。 (我需要将对象列表打印到 html 表中以发送电子邮件)
      【解决方案5】:

      周围有几个模板库(Genshi 是我喜欢的一个,但还有很多其他的)。

      或者,您可以执行以下操作:

      def print_table(data, row_length):
          print '<table>'
          counter = 0
          for element in data:
              if counter % row_length == 0:
                  print '<tr>'
              print '<td>%s</td>' % element
              counter += 1
              if counter % row_length == 0:
                  print '</tr>'
          if counter % row_length != 0:
              for i in range(0, row_length - counter % row_length):
                  print '<td>&nbsp;</td>'
              print '</tr>'
          print '</table>'
      

      【讨论】:

      • OP 确实希望避免嵌套 for 循环。所以可能是对 map(lambda) 的介绍。
      • @whatnick - 你看到循环中的循环了吗?我没有。
      【解决方案6】:

      也许对于玩具代码来说操作模板更容易,=p

      def get_html_tbl(seq, col_count):
          if len(seq) % col_count:
              seq.extend([''] * (col_count - len(seq) % col_count))
          tbl_template = '<table>%s</table>' % ('<tr>%s</tr>' % ('<td>%s</td>' * col_count) * (len(seq)/col_count))
          return tbl_template % tuple(seq)
      

      【讨论】:

        【解决方案7】:

        虽然之前已经回答过这个问题,但这里是另一个使用 numpypandas DataFrame 的解决方案。由于现在很多人都对数据科学感兴趣,我认为使用 pandas 解决这个问题会很有趣:

        GITHUB 解决方案:
        我在my GitHub Repository 上提供了我的solution,您也可以在Google Colaboratory 中运行和探索它(我强烈推荐这个)。

        我在此处使用的自定义函数 (generate_html_with_table()) 在此Jupyter Notebook 中可用。

        解决方案:
        要获得您的解决方案,请运行以下命令:

        data = ['one','two','three','four','five','six','seven','eight','nine']
        columns = 4                   # Number of Columns
        columns_or_rows = columns
        column_name_prefix = 'Column' # Prefix for Column headers
        span_axis = 1                 # Span along a row (1) or a column (0) first
        showOutput = True             # Use False to suppress printing output
        
        # Generate HTML
        data_html, data_df = generate_html_with_table(data, columns_or_rows, column_name_prefix, span_axis, showOutput)
        

        输出:

        HTML Generated: 
        
        <table border="1" class="dataframe">
          <thead>
            <tr style="text-align: right;">
              <th></th>
              <th>Column_0</th>
              <th>Column_1</th>
              <th>Column_2</th>
              <th>Column_3</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <th>0</th>
              <td>one</td>
              <td>two</td>
              <td>three</td>
              <td>four</td>
            </tr>
            <tr>
              <th>1</th>
              <td>five</td>
              <td>six</td>
              <td>seven</td>
              <td>eight</td>
            </tr>
            <tr>
              <th>2</th>
              <td>nine</td>
              <td></td>
              <td></td>
              <td></td>
            </tr>
          </tbody>
        </table>
        

        code_output_with_spanning_along_a_row

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-06-21
          • 1970-01-01
          • 2013-08-18
          • 1970-01-01
          • 2010-12-06
          • 1970-01-01
          • 2017-11-03
          • 1970-01-01
          相关资源
          最近更新 更多