from functools import reduce


def createLookup(B):
    """Process B to create a reverse lookup scheme that is appropriate for
    any of the libraries in pyncomb that allow for one or more base sets to
    be specified.

    Let rev(K) be the reverse lookup dictionary of a list K, i.e. if
    K[i] = j, then rev(K)[j] = i.

    If B is an integer, then return B.
    If B is a flat list, then return a pair (B,rev(B)).
    If B is a list of lists / integers, then return a list Bn with:
       1. Bn[i] = B[i] if B[i] is an integer.
       2. Bn[i] = (B[i], rev(B[i])) if B[i] is a list.

    For example, createLookup can translate a base set specification of:
        [4,['a','b','c'],[11,22]]
    which represents three base sets [0,1,2,3], ['a','b','c'], [11,22].
    The returned data will consist of base sets with their reverse lookup
    data and can be used as the B parameter in any function."""

    # Handle integers.
    if type(B) == int:
        return B

    # Handle flat lists.
    if reduce(lambda a,b:a and b, [type(i) != list for i in B], True):
        return (B, dict([(B[i], i) for i in range(len(B))]))

    # Handle nested lists.
    Bn = []
    for D in B:
        if type(D) == int:
            Bn.append(D)
        else:
            Bn.append((D, dict([(D[i],i) for i in range(len(D))])))
    return Bn