docs: def list_to_obj(cls, list_, columns, row_columns=None, tab='',
                      key_on=None, no_header=False):
          """
          :param list_:         list of list or list of dictionary to use as the
                                source
          :param columns:       list of strings to label the columns when
                                converting to str
          :param row_columns:   list of columns in the actually data
          :param tab:           str of the tab to use before the row when
                                converting to str
          :param key_on:        str of the column to key each row on
          :param no_header:     bool if false then the first row is the headers
          :return: SeabornTable
          """
          if not list_:
              return cls(columns=columns, row_columns=row_columns, tab=tab,
                         key_on=key_on)
          if getattr(list_[0], 'keys', None) and not isinstance(list_[0], dict):
              row_columns = row_columns or columns or list_[0].keys()
              column_index = cls._create_column_index(row_columns)
              table = [SeabornRow(
                  column_index,
                  [getattr(row, col, None) for col in row_columns])
                  for row in list_]
          elif isinstance(list_[0], dict):
              row_columns = row_columns or columns or \
                            cls._key_on_columns(key_on,
                                                cls._get_normalized_columns(
                                                    list_))
              column_index = cls._create_column_index(row_columns)
              table = [SeabornRow(column_index,
                                  [row.get(c, None) for c in row_columns])
                       for row in list_]
  
          elif isinstance(list_[0], (list, tuple)) and no_header:
              row_columns = row_columns or columns or \
                            cls._key_on_columns(key_on, [
                                'Column %s' % i for i in range(len(list_[0]))])
              column_index = cls._create_column_index(row_columns)
              table = [SeabornRow(column_index, row) for row in list_]
  
          elif isinstance(list_[0], (list, tuple)):
              row_columns = row_columns or list_[0]
              if list_[0] == row_columns:
                  list_ = list_[1:]
              column_index = cls._create_column_index(row_columns)
              size = len(row_columns)
              table = [SeabornRow(column_index, row + [None] * (size - len(row)))
                       for row in list_]
          else:
              column_index = cls._create_column_index(columns or [])
              table = [SeabornRow(column_index, [row]) for row in list_]
  
          return cls(table, columns, row_columns, tab, key_on)