29

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

['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 库,但我没有时间逐个查看它们是否可以很好地处理表格。有没有人不得不这样做?如果是这样,你是怎么做到的?

4

7 回答 7

35

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

  • 给定一个“平面列表”,生成一个子列表列表,其中子列表具有给定长度,并且整个列表可以按“行专业”顺序(您的第一个和第三个示例)或“列专业”(您的第二个例子);
  • 给定一个包含字符串项的子列表列表,从中生成一个 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>'

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

现在你有了两个简单、有用、可用和可重用的构建块——只要你想将数据呈现为 HTML 表格以外的任何东西,以及将列表列表呈现为 HTML 时,将它们分开就会派上用场table 来自任何其他构建它的方式。在您的应用程序代码中将它们放在一起很容易,但当然也很容易做一个简单的“粘合例程”,例如,假设yield基于 - 的版本html_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))

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

于 2009-09-25T04:36:28.250 回答
33

使用表格

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>
于 2019-03-02T22:02:23.783 回答
11

只是为了将来参考,我实现了一个名为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")

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

于 2014-08-06T14:27:49.737 回答
6

另一个选择是漂亮的:

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以获得更多选项,例如启用不同类型的样式。

请享用。

于 2019-08-23T09:36:43.610 回答
2

好吧,周围有几个模板库(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>'
于 2009-09-25T02:33:15.353 回答
0

也许对于玩具代码来说操作模板更容易,=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)
于 2009-09-25T08:03:23.697 回答
0

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

GITHUB 解决方案:
我在我的 GitHub 存储库中提供了我的解决方案,您也可以在 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

于 2018-08-23T20:38:02.437 回答