def create_typo_table(typo_chars, score=3):
    """Create a dictionary mapping typographically similar characters to each
    other.

    Input is a list (of even length) of characters. The characters are
    assummed to be listed in pairs, and their presence states that the first
    character is typographically similar to the second.

    Each pairing of similar characters is given the value (the 'score'
    argument). The Jaro-Winkler routines use this score to increase the
    amount of characters matching in their input strings.

    An example:

    >>> typo_chars = ['B', '8', '0', 'O', '0', 'Q', 'I', 'l']
    >>> typo_table = create_typo_table(typo_chars, score=2)

    This function returns a symmetrical dictionary of dictionaries:

    >>> typo_table['B']['8'] == typo_table['8']['B']
    True

    ... but note that this symmetry is not carried through in future
    assignments:

    >>> typo_table['8']['B'] = 5
    >>> print_typo_table(typo_table)
      08BIOQl
     +-------+
    0|....22.|0
    8|..5....|8
    B|.2.....|B
    I|......2|I
    O|2......|O
    Q|2......|Q
    l|...2...|l
     +-------+
      08BIOQl
    """
    typo_table = {}
    for i in range(len(typo_chars) // 2):
        row_char = typo_chars[i * 2]
        col_char = typo_chars[i * 2 + 1]
        for row, col in [(row_char, col_char), (col_char, row_char)]:
            try:
                row_dict = typo_table[row]
            except KeyError:
                typo_table[row] = row_dict = {}
            if col in row_dict:
                msg = 'Redundant entry (%s) in typo_chars.' % col
                raise ValueError(msg)
            row_dict[col] = score
    return typo_table
