2009-09-25 17 views
11

Digamos que tengo una lista de este modo:¿La forma más fácil de convertir una lista en una tabla HTML en python?

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

y quiero experimentar con convertir estos datos en una tabla HTML de varias dimensiones:

one  two three 
four five six 
seven eight nine 

o

one four seven 
two five eight 
three six nine 

o

one two three four 
five six seven eight 
nine 

¿Hay una biblioteca que pueda manejar esto sin necesidad de hacer un empalme de listas locas o anidados para bucles? Mis búsquedas en Google revelan que hay algunas bibliotecas HTML, pero no tengo tiempo para revisar cada una de ellas para ver si pueden manejar las tablas muy bien. ¿Alguien ha tenido que hacer esto alguna vez? ¿Si es así, cómo lo hiciste?

Respuesta

26

Me descomponer el problema en dos partes:

  • dado una "lista plana", producir una lista de sublistas, donde las sublistas son de una longitud determinada y la lista general puede entrar en una orden "fila mayor" (su primer y tercer ejemplo) o "columna mayor" (su segundo ejemplo);
  • dado una lista de sublistas con elementos de cadena, producir una tabla HTML de la misma.

Creo que las dos tareas son realmente muy distintas y no hay nada que ganar (y mucho que perder) al revivirlas, así que me sorprendería si alguna biblioteca bien diseñada hiciera tal mushing.

Para el punto 1, fila-mayor es fácil:

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

y la columna-principal no es tan malo:

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

por ejemplo ...:

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 

produce sus tres resultados deseados (una lista por fila, no en formato HTML todavía ;-).

La segunda mitad del problema - producir una tabla HTML de una lista de listas de cadenas:

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

Si desea obtener como una sola cadena en lugar de imprimirlo, cambiar cada print en yield y usa '\n'.join(html_table(lol)).

Ahora tiene dos bloques de construcción simples, útiles, utilizables y reutilizables: tenerlos por separado le serán útiles cuando quiera presentar sus datos como algo más que una tabla HTML, y siempre que la lista de listas para presente como una tabla HTML proviene de cualquier otra forma de construirlo.Ponerlos juntos es fácil de hacer en el código de aplicación, pero por supuesto también es fácil de hacer un simple "rutina de pegamento", por ejemplo, suponiendo que el yield versión basada de html_table y que se desea una sola cadena resultado:

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

no es esto bloques de construcción se aproximan muy agradable y más agradable, así como la más productiva, que la programación en términos de grandes gotas de pegamento mushed arriba ... -?)

2

Bueno, hay varias bibliotecas de plantillas alrededor (Genshi es una que me gusta pero hay muchas otras).

Alternativamente, usted podría hacer algo como:

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>' 
+0

El OP quería evitar bucles anidados. Entonces puede ser una introducción al mapa (lambda) está en orden. – whatnick

+2

@whatnick - ¿Ves un bucle dentro de un bucle? Yo no. –

+0

Solo un lazo simple. – whatnick

0

Tal vez es más fácil manipular la plantilla para códigos de juguete, = 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) 
3

Solo como referencia futura, implementé un pequeño módulo de Python llamado simpletable para proporcionar una generación fácil de tablas HTML. También se trata del problema descrito en esta pregunta.

El uso es tan sencillo como a continuación:

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

Dado que no requiere de paquetes de terceros, sólo se puede obtener el código de my repository y utilizarlo en sus proyectos.

Cuestiones relacionadas