# Buggy code
def _write_hierarchical_rows(self, fmt_values, indent):
    template = 'rowspan="{span}" valign="top"'

    truncate_h = self.fmt.truncate_h
    truncate_v = self.fmt.truncate_v
    frame = self.fmt.tr_frame
    nrows = len(frame)
    # TODO: after gh-22887 fixed, refactor to use class property
    # in place of row_levels
    row_levels = self.frame.index.nlevels

    idx_values = frame.index.format(sparsify=False, adjoin=False, names=False)
    idx_values = lzip(*idx_values)

    if self.fmt.sparsify:
        # GH3547
        sentinel = com.sentinel_factory()
        levels = frame.index.format(sparsify=sentinel, adjoin=False, names=False)

        level_lengths = get_level_lengths(levels, sentinel)
        inner_lvl = len(level_lengths) - 1
        if truncate_v:
            # Insert ... row and adjust idx_values and
            # level_lengths to take this into account.
            ins_row = self.fmt.tr_row_num
            inserted = False
            for lnum, records in enumerate(level_lengths):
                rec_new = {}
                for tag, span in list(records.items()):
                    if tag >= ins_row:
                        rec_new[tag + 1] = span
                    elif tag + span > ins_row:
                        rec_new[tag] = span + 1

                        # GH 14882 - Make sure insertion done once
                        if not inserted:
                            dot_row = list(idx_values[ins_row - 1])
                            dot_row[-1] = u("...")
                            idx_values.insert(ins_row, tuple(dot_row))
                            inserted = True
                        else:
                            dot_row = list(idx_values[ins_row])
                            dot_row[inner_lvl - lnum] = u("...")
                            idx_values[ins_row] = tuple(dot_row)
                    else:
                        rec_new[tag] = span
                    # If ins_row lies between tags, all cols idx cols
                    # receive ...
                    if tag + span == ins_row:
                        rec_new[ins_row] = 1
                        if lnum == 0:
                            idx_values.insert(
                                ins_row, tuple([u("...")] * len(level_lengths))
                            )

                        # GH 14882 - Place ... in correct level
                        elif inserted:
                            dot_row = list(idx_values[ins_row])
                            dot_row[inner_lvl - lnum] = u("...")
                            idx_values[ins_row] = tuple(dot_row)
                level_lengths[lnum] = rec_new

            level_lengths[inner_lvl][ins_row] = 1
            for ix_col in range(len(fmt_values)):
                fmt_values[ix_col].insert(ins_row, "...")
            nrows += 1

        for i in range(nrows):
            row = []
            tags = {}

            sparse_offset = 0
            j = 0
            for records, v in zip(level_lengths, idx_values[i]):
                if i in records:
                    if records[i] > 1:
                        tags[j] = template.format(span=records[i])
                else:
                    sparse_offset += 1
                    continue

                j += 1
                row.append(v)

            row.extend(fmt_values[j][i] for j in range(self.ncols))
            if truncate_h:
                row.insert(row_levels - sparse_offset + self.fmt.tr_col_num, "...")
            self.write_tr(
                row,
                indent,
                self.indent_delta,
                tags=tags,
                nindex_levels=len(levels) - sparse_offset,
            )
    else:
        for i in range(len(frame)):
            idx_values = list(
                zip(*frame.index.format(sparsify=False, adjoin=False, names=False))
            )
            row = []
            row.extend(idx_values[i])
            row.extend(fmt_values[j][i] for j in range(self.ncols))
            if truncate_h:
                row.insert(row_levels + self.fmt.tr_col_num, "...")
            self.write_tr(
                row,
                indent,
                self.indent_delta,
                tags=None,
                nindex_levels=frame.index.nlevels,
            )


# Traceback (TypeError)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-24-59e289592884> in <module>()
3           ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
4 df = pd.DataFrame(index=arrays, columns=arrays)
----> 5 df.to_html(max_cols=7, sparsify=False)

~\Anaconda3\lib\site-packages\pandas\core\frame.py in to_html(self, buf, columns, col_space, header, index, na_rep, formatters, float_format, sparsify, index_names, justify, bold_rows, classes, escape, max_rows, max_cols, show_dimensions, notebook, decimal, border, table_id)
2032                                            decimal=decimal, table_id=table_id)
2033         # TODO: a generic formatter wld b in DataFrameFormatter
-> 2034         formatter.to_html(classes=classes, notebook=notebook, border=border)
2035
2036         if buf is None:

~\Anaconda3\lib\site-packages\pandas\io\formats\format.py in to_html(self, classes, notebook, border)
749                                       table_id=self.table_id)
750         if hasattr(self.buf, 'write'):
--> 751             html_renderer.write_result(self.buf)
752         elif isinstance(self.buf, compat.string_types):
753             with open(self.buf, 'w') as f:

~\Anaconda3\lib\site-packages\pandas\io\formats\html.py in write_result(self, buf)
177
178         indent += self.indent_delta
--> 179         indent = self._write_header(indent)
180         indent = self._write_body(indent)
181

~\Anaconda3\lib\site-packages\pandas\io\formats\html.py in _write_header(self, indent)
279                         recs_new[ins_col] = 1
280                         records = recs_new
--> 281                         values = (values[:ins_col] + [u('...')] +
282                                   values[ins_col:])
283

TypeError: can only concatenate tuple (not "list") to tuple

# Fixed code
def _write_hierarchical_rows(self, fmt_values, indent):
    template = 'rowspan="{span}" valign="top"'

    truncate_h = self.fmt.truncate_h
    truncate_v = self.fmt.truncate_v
    frame = self.fmt.tr_frame
    nrows = len(frame)

    idx_values = frame.index.format(sparsify=False, adjoin=False, names=False)
    idx_values = lzip(*idx_values)

    if self.fmt.sparsify:
        # GH3547
        sentinel = com.sentinel_factory()
        levels = frame.index.format(sparsify=sentinel, adjoin=False, names=False)

        level_lengths = get_level_lengths(levels, sentinel)
        inner_lvl = len(level_lengths) - 1
        if truncate_v:
            # Insert ... row and adjust idx_values and
            # level_lengths to take this into account.
            ins_row = self.fmt.tr_row_num
            inserted = False
            for lnum, records in enumerate(level_lengths):
                rec_new = {}
                for tag, span in list(records.items()):
                    if tag >= ins_row:
                        rec_new[tag + 1] = span
                    elif tag + span > ins_row:
                        rec_new[tag] = span + 1

                        # GH 14882 - Make sure insertion done once
                        if not inserted:
                            dot_row = list(idx_values[ins_row - 1])
                            dot_row[-1] = u("...")
                            idx_values.insert(ins_row, tuple(dot_row))
                            inserted = True
                        else:
                            dot_row = list(idx_values[ins_row])
                            dot_row[inner_lvl - lnum] = u("...")
                            idx_values[ins_row] = tuple(dot_row)
                    else:
                        rec_new[tag] = span
                    # If ins_row lies between tags, all cols idx cols
                    # receive ...
                    if tag + span == ins_row:
                        rec_new[ins_row] = 1
                        if lnum == 0:
                            idx_values.insert(
                                ins_row, tuple([u("...")] * len(level_lengths))
                            )

                        # GH 14882 - Place ... in correct level
                        elif inserted:
                            dot_row = list(idx_values[ins_row])
                            dot_row[inner_lvl - lnum] = u("...")
                            idx_values[ins_row] = tuple(dot_row)
                level_lengths[lnum] = rec_new

            level_lengths[inner_lvl][ins_row] = 1
            for ix_col in range(len(fmt_values)):
                fmt_values[ix_col].insert(ins_row, "...")
            nrows += 1

        for i in range(nrows):
            row = []
            tags = {}

            sparse_offset = 0
            j = 0
            for records, v in zip(level_lengths, idx_values[i]):
                if i in records:
                    if records[i] > 1:
                        tags[j] = template.format(span=records[i])
                else:
                    sparse_offset += 1
                    continue

                j += 1
                row.append(v)

            row.extend(fmt_values[j][i] for j in range(self.ncols))
            if truncate_h:
                row.insert(self.row_levels - sparse_offset + self.fmt.tr_col_num, "...")
            self.write_tr(
                row,
                indent,
                self.indent_delta,
                tags=tags,
                nindex_levels=len(levels) - sparse_offset,
            )
    else:
        row = []
        for i in range(len(frame)):
            if truncate_v and i == (self.fmt.tr_row_num):
                str_sep_row = ["..."] * len(row)
                self.write_tr(
                    str_sep_row,
                    indent,
                    self.indent_delta,
                    tags=None,
                    nindex_levels=self.row_levels,
                )

            idx_values = list(
                zip(*frame.index.format(sparsify=False, adjoin=False, names=False))
            )
            row = []
            row.extend(idx_values[i])
            row.extend(fmt_values[j][i] for j in range(self.ncols))
            if truncate_h:
                row.insert(self.row_levels + self.fmt.tr_col_num, "...")
            self.write_tr(
                row,
                indent,
                self.indent_delta,
                tags=None,
                nindex_levels=frame.index.nlevels,
            )