def parseCSV(csvList, header=True, columns=[], types=False, coltypes={},
    allowEmpty=False, emptyCols=[]):
    """
    Given a CSV parsed into a list of lists, convert it into a list of dictionaries, either with the first line
    as headers or with a specified column order.

    If types is true, it will also parse the entries according to the parsing functions in coltypes; if not,
    it will leave them all as strings.  coltypes must be specified if types is True.  coltypes should be a dictionary
    of {column: parser}, e.g. {"profilenumber": int}.

    The empty-related parameters are ignored unless types is True.  If types are being used, then, if an entry is empty:
        * If allowEmpty is false, then the function will throw an error if the column name is not in emptyCols, or
            if it is, then the value will be set to None.
        * If allowEmpty is true, then the value will be set to None.
    This does not apply if the specified type is string.
    """
    if header:
        columns = csvList[0]
    cols = len(columns)
    result = []
    start = 1 if header else 0
    for row in csvList[start:]:
        count = len(row)
        if count != cols:
            if row == [] or row == ['']:
                continue
            raise ValueError(
                'Error: number of columns is not consistent in row: %s' % row)
        out = {}
        for i in range(0, count):
            val = row[i]
            col = columns[i]
            if types:
                if val == '':
                    if coltypes[col] == str:
                        out[col] = val
                    elif allowEmpty == True or col in emptyCols:
                        out[col] = None
                    else:
                        raise ValueError(
                            'Error: empty entry not allowed in row: %s' % row)
                else:
                    out[col] = coltypes[col](val)
            else:
                out[col] = val
        result.append(out)
    return result
