def dimensionalIterator(dimensions, maxItems=-1):
    """
    Given a list of n positive integers, return a generator that yields
    n-tuples of coordinates to 'fill' the dimensions. This is like an
    odometer in a car, but the dimensions do not each have to be 10.

    For example: dimensionalIterator((2, 3)) will yield in order
    (0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2). See the tests in
    test_dimension.py for many more examples.

    A dimension may also be given as '*', to provide a dimension that is
    never exhausted. For example, dimensionalIterator(('*', 2)) yields the
    infinite series (0, 0), (0, 1), (1, 0), (1, 1), (2, 0), (2, 1), ....

    maxItems can be used to limit the number of tuples yielded.
    """
    nDimensions = len(dimensions)
    if nDimensions == 0 or maxItems == 0:
        return
    if any(map(lambda x: x != '*' and x <= 0, dimensions)):
        raise ValueError
    odometer = [0, ] * nDimensions
    while maxItems != 0:
        yield tuple(odometer)
        maxItems -= 1
        wheel = nDimensions - 1
        while (dimensions[wheel] != '*' and
               odometer[wheel] == dimensions[wheel] - 1 and
               wheel >= 0):
            odometer[wheel] = 0
            wheel -= 1
        if wheel < 0:
            return
        odometer[wheel] += 1
