'Inserts a column to the :class:`Dataset` at the given index.
Columns inserted must be the correct height.
You can also insert a column of a single callable object, which will
add a new column with the return values of the callable each as an
item in the column. ::
data.append_col(col=random.randint)
If inserting a column, and :class:`Dataset.headers` is set, the
header attribute must be set, and will be considered the header for
that row.
See :ref:`dyncols` for an in-depth example.
.. versionchanged:: 0.9.0
If inserting a column, and :class:`Dataset.headers` is set, the
header attribute must be set, and will be considered the header for
that row.
.. versionadded:: 0.9.0
If inserting a row, you can add :ref:`tags <tags>` to the row you are inserting.
This gives you the ability to :class:`filter <Dataset.filter>` your
:class:`Dataset` later.'

def insert_col(self, index, col=None, header=None):

    if (col is None):
        col = []
    if hasattr(col, '__call__'):
        col = list(map(col, self._data))
    col = self._clean_col(col)
    self._validate(col=col)
    if self.headers:
        if (not header):
            raise HeadersNeeded()
        elif (header and (self.height == 0) and len(col)):
            raise InvalidDimensions
        self.headers.insert(index, header)
    if (self.height and self.width):
        for (i, row) in enumerate(self._data):
            row.insert(index, col[i])
            self._data[i] = row
    else:
        self._data = [Row([row]) for row in col]
