I have a list of tuples in Python that I would like to output to a table in reStructuredText.
The docutils library has great support for converting reStructuredText to other formats, but I want to write directly from a data structure in memory to reStructuredText.
I'm not aware of any libraries to output RST from python data structures, but it's pretty easy to format it yourself. Here's an example of formatting a list of python tuples to an RST table:
>>> data = [('hey', 'stuff', '3'),
('table', 'row', 'something'),
('xy', 'z', 'abc')]
>>> numcolumns = len(data[0])
>>> colsizes = [max(len(r[i]) for r in data) for i in range(numcolumns)]
>>> formatter = ' '.join('{:<%d}' % c for c in colsizes)
>>> rowsformatted = [formatter.format(*row) for row in data]
>>> header = formatter.format(*['=' * c for c in colsizes])
>>> output = header + '\n' + '\n'.join(rowsformatted) + '\n' + header
>>> print output
===== ===== =========
hey stuff 3
table row something
xy z abc
===== ===== =========
Check out the tabulate package. It can output RST format by:
print tabulate(table, headers, tablefmt="rst")
>> print make_table([['Name', 'Favorite Food', 'Favorite Subject'],
['Joe', 'Hamburgers', 'Cars'],
['Jill', 'Salads', 'American Idol'],
['Sally', 'Tofu', 'Math']])
+------------------+------------------+------------------+
| Name | Favorite Food | Favorite Subject |
+==================+==================+==================+
| Joe | Hamburgers | Cars |
+------------------+------------------+------------------+
| Jill | Salads | American Idol |
+------------------+------------------+------------------+
| Sally | Tofu | Math |
+------------------+------------------+------------------+
Here is the code I use for quick and dirty reStructuredText tables:
def make_table(grid):
cell_width = 2 + max(reduce(lambda x,y: x+y, [[len(item) for item in row] for row in grid], []))
num_cols = len(grid[0])
rst = table_div(num_cols, cell_width, 0)
header_flag = 1
for row in grid:
rst = rst + '| ' + '| '.join([normalize_cell(x, cell_width-1) for x in row]) + '|\n'
rst = rst + table_div(num_cols, cell_width, header_flag)
header_flag = 0
return rst
def table_div(num_cols, col_width, header_flag):
if header_flag == 1:
return num_cols*('+' + (col_width)*'=') + '+\n'
else:
return num_cols*('+' + (col_width)*'-') + '+\n'
def normalize_cell(string, length):
return string + ((length - len(string)) * ' ')
@cieplak's answer was great. I refined it a bit so that columns are sized independently
print make_table( [ ['Name', 'Favorite Food', 'Favorite Subject'],
['Joe', 'Hamburgrs', 'I like things with really long names'],
['Jill', 'Salads', 'American Idol'],
['Sally', 'Tofu', 'Math']])
===== ============= ====================================
Name Favorite Food Favorite Subject
===== ============= ====================================
Joe Hamburgrs I like things with really long names
----- ------------- ------------------------------------
Jill Salads American Idol
----- ------------- ------------------------------------
Sally Tofu Math
===== ============= ====================================
Here is the code
def make_table(grid):
max_cols = [max(out) for out in map(list, zip(*[[len(item) for item in row] for row in grid]))]
rst = table_div(max_cols, 1)
for i, row in enumerate(grid):
header_flag = False
if i == 0 or i == len(grid)-1: header_flag = True
rst += normalize_row(row,max_cols)
rst += table_div(max_cols, header_flag )
return rst
def table_div(max_cols, header_flag=1):
out = ""
if header_flag == 1:
style = "="
else:
style = "-"
for max_col in max_cols:
out += max_col * style + " "
out += "\n"
return out
def normalize_row(row, max_cols):
r = ""
for i, max_col in enumerate(max_cols):
r += row[i] + (max_col - len(row[i]) + 1) * " "
return r + "\n"
You can choose to dump into a CSV from Python and then use the csv-table feature of RST as in http://docutils.sourceforge.net/docs/ref/rst/directives.html#csv-table It has got a :file: directive to simply include a csv file with data.
Here's @cieplak's code adding conversion to string and multiline support. Maybe it will be of use to someone.
def make_table(grid):
cell_width = 2 + max(reduce(lambda x,y: x+y, [[max(map(len, str(item).split('\n'))) for item in row] for row in grid], []))
num_cols = len(grid[0])
rst = table_div(num_cols, cell_width, 0)
header_flag = 1
for row in grid:
split_row = [str(cell).split('\n') for cell in row]
lines_remaining = 1
while lines_remaining>0:
normalized_cells = []
lines_remaining = 0
for cell in split_row:
lines_remaining += len(cell)
if len(cell) > 0:
normalized_cell = normalize_cell(str(cell.pop(0)), cell_width - 1)
else:
normalized_cell = normalize_cell('', cell_width - 1)
normalized_cells.append(normalized_cell)
rst = rst + '| ' + '| '.join(normalized_cells) + '|\n'
rst = rst + table_div(num_cols, cell_width, header_flag)
header_flag = 0
return rst
来源:https://stackoverflow.com/questions/11347505/what-are-some-approaches-to-outputting-a-python-data-structure-to-restructuredte