What are some approaches to outputting a Python data structure to reStructuredText

后端 未结 6 532
星月不相逢
星月不相逢 2020-12-31 18:21

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

相关标签:
6条回答
  • 2020-12-31 18:55

    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      
    ===== ===== =========
    
    0 讨论(0)
  • 2020-12-31 19:01

    @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"
    
    0 讨论(0)
  • 2020-12-31 19:08

    Check out the tabulate package. It can output RST format by:

    print tabulate(table, headers, tablefmt="rst")
    
    0 讨论(0)
  • 2020-12-31 19:11

    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
    
    0 讨论(0)
  • 2020-12-31 19:13

    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.

    0 讨论(0)
  • 2020-12-31 19:17
    >> 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)) * ' ')
    
    0 讨论(0)
提交回复
热议问题