it-swarm.com.ru

Самый простой способ превратить список в таблицу HTML в Python?

допустим, у меня есть список вроде так:

['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

Есть ли библиотека, которая может справиться с этим без необходимости сумасшедшего объединения списков или вложенных циклов? Мои поиски в Google показывают, что есть несколько библиотек HTML, но у меня нет времени, чтобы просмотреть каждую из них, чтобы увидеть, могут ли они очень хорошо обрабатывать таблицы. Кто-нибудь когда-либо должен был это делать? Если да, то как ты это сделал?

12
priestc

Я бы разбил вашу проблему на две части:

  • если задан "плоский список", создайте список подсписков, в котором подсписки имеют заданную длину, а общий список можно переместить в порядке "основного ряда" (ваш первый и третий пример) или "основного столбца" (ваш второй). пример);
  • учитывая список подсписков со строковыми элементами, создайте из него таблицу HTML.

Я думаю, что эти две задачи на самом деле очень разные, и нечего их выиграть (и многое можно потерять), поэтому я был бы удивлен, если бы такая хорошая задача была в какой-нибудь хорошо спроектированной библиотеке.

Для пункта 1 основной ряд прост:

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. Стол происходит от любого другого способа его построения. Объединить их легко в коде приложения, но, конечно, также легко выполнить простую "подпрограмму склейки", например, предполагая версию html_table, основанную на yield, и желаемый результат в виде одной строки:

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))

Разве этот подход на основе стандартных блоков не является более приятным и более приятным, а также более продуктивным, чем программирование с точки зрения больших капель растертого клея ...? -)

27
Alex Martelli

Просто для дальнейшего использования, я реализовал небольшой модуль Python, называемый simpletable , чтобы обеспечить легкую генерацию таблицы 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")

Поскольку для этого не требуются сторонние пакеты, вы можете просто получить код из мой репозиторий и использовать его в своих проектах.

5
Matheus Portela

Ну, есть несколько шаблонных библиотек (мне нравится Генши, но есть много других).

В качестве альтернативы вы можете сделать что-то вроде:

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>'
2
Benno

Хотя на этот вопрос уже был дан ответ, здесь есть другое решение с использованием numpy и панд DataFrame . Поскольку сегодня многие люди интересуются наукой о данных, я подумал, что решить эту проблему с помощью pandas было бы весело:

РЕШЕНИЕ GITHUB:
Я сделал мое решение доступным на мой репозиторий GitHub , которое вы также можете запустить и изучить в Google Colab Laboratory (я настоятельно рекомендую это).

Пользовательская функция (generate_html_with_table()), которую я здесь использовал, доступна в этом блокноте Jupyter .

РЕШЕНИЕ:
Чтобы получить решение, выполните следующее:

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

0
CypherX

Возможно манипулировать шаблоном проще для игрушечных кодов, = 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)
0
okm