2
\$\begingroup\$

I have created a module to draw text tables. The relevant parts are below and here's the full code for txtable).

class Row(Txtable):
    [...]
    def format(self, col_widths):
        """Return the row as formatted string.
        """

        columns = []
        for x, column in enumerate(self.columns):
            # skip empty rows
            if 0 == len(str(column)):
                columns.append((" " * col_widths[x]))
                continue
            columns.append(self.format_cell(x, col_widths[x]))
        return str(" " * self.col_spacing).join(columns)


class Table(Txtable):
    [...]
    def add_rows(self, rows):
        """Add multiple rows.
        """

        for columns in rows:
            self.add_row(columns)

    [...]
    def render(self):
        """Return the table as a string.
        """

        # render cells and measure column widths
        for y, row in enumerate(self.rows):
            for x, column in enumerate(row.columns):
                fmt_column = row.format_cell(x)
                width = len(fmt_column)
                try:
                    if self.col_widths[x] < width:
                        self.col_widths[x] = width
                except IndexError:
                    self.col_widths.append(width)
        # render the table with proper spacing
        output = ""
        lmarg = (" " * self.margin)
        for row in self.rows:
            [...do rest of the rendering...]

I'd like to know about ways I could optimize this please. I see I could calculate the maximum column widths in Table.add_rows() instead of Table.render(), but I'd like to keep the possibility to modify the rows before rendering the final output.

How could I cut back on the looping? Is there a better way to output tabular data?

\$\endgroup\$

closed as off-topic by Sᴀᴍ Onᴇᴌᴀ, Stephen Rauch, Billal Begueradj, Snowhawk, Daniel Jul 1 '18 at 15:27

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Lacks concrete context: Code Review requires concrete code from a project, with sufficient context for reviewers to understand how that code is used. Pseudocode, stub code, hypothetical code, obfuscated code, and generic best practices are outside the scope of this site." – Sᴀᴍ Onᴇᴌᴀ, Stephen Rauch, Billal Begueradj, Snowhawk, Daniel
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 1
    \$\begingroup\$ This code doesn't run: you must post working code for us to review. \$\endgroup\$ – Gareth Rees Nov 22 '13 at 16:55
  • 1
    \$\begingroup\$ It would make more sense to review the complete code. (You need to post it here then) \$\endgroup\$ – Janne Karila Nov 24 '13 at 18:24
1
\$\begingroup\$

The nested loop under # render cells and measure column widths computes maximum cell width of each column. Using itertools.zip_longest to turn columns into rows lets you use max on them:

cell_widths = [[len(row.format_cell(x)) for x in range(len(row.columns))]
                for row in self.rows]
col_widths = list(map(max, itertools.zip_longest(*cell_widths, fillvalue=0)))
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.