如何将Python数据结构输出为reStructuredText的方法有哪些?

9
我有一个Python元组列表,我想将其输出到reStructuredText表格中。
docutils库支持将reStructuredText转换为其他格式,但我希望直接从内存中的数据结构编写reStructuredText。
6个回答

9

可以看看 tabulate 包。 它可以通过以下方式输出 RST 格式:

print tabulate(table, headers, tablefmt="rst")

6

我不知道是否有任何库可以将Python数据结构输出为RST格式,但是如果你自己格式化一下的话,这很容易实现。以下是一个示例,将Python元组列表格式化为RST表格:

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

6
>> 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             |
+------------------+------------------+------------------+

这是我用于快速创建reStructuredText表格的代码:
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)) * ' ')

2

@cieplak的回答很好,我稍微修改了一下,使得每列可以独立调整大小。

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

这里是代码

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"

1

0
这是 @cieplak 的代码,添加了转换为字符串和多行支持。也许对某些人有用。
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接