tree functions daily exercise: Table

Duncan Booth duncan.booth at invalid.invalid
Wed Jun 22 04:51:07 EDT 2005


Duncan Booth wrote:
> Ok, so, if I understand you, the definition of Table is just:
> 
> def Table(f, *lists):
>     return Outer(f,
>         *[range(start,end+1,step) for (start,end,step) in lists])
> 
> Is that about right?
> 

And lest you think I left a bit too much as an "exercise for the
reader": 

-------------- xah.py --------------------
def Table(f, *lists):
    """Xah Lee's Table function
    >>> Table(f,[3,10,2])
    [f(3), f(5), f(7), f(9)]
    >>> Table(f,[1,2,1],[2,6,2])
    [[f(1, 2), f(1, 4), f(1, 6)], [f(2, 2), f(2, 4), f(2, 6)]]
    """
    return Outer(f, *[range(start,end+1,step) for (start,end,step) in lists])

def explode(lists):
    """Form all combinations of 1 element from each list.
    >>> explode([[1,2], [3]])
    [(1, 3), (2, 3)]
    >>> explode([[1,2], [3,4]])
    [(1, 3), (1, 4), (2, 3), (2, 4)]
    >>> explode([[1,2], [3,4], [5]])
    [(1, 3, 5), (1, 4, 5), (2, 3, 5), (2, 4, 5)]
    """
    result = [()]
    for l in lists[::-1]:
        result = [ (val,) + tail for val in l for tail in result ]

    return result

def groupsOfN(it, n):
    """Returns tuples of length n taken from it.
    >>> groupsOfN(range(12), 3)
    [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]
    >>> groupsOfN(range(12), 1)
    [(0,), (1,), (2,), (3,), (4,), (5,), (6,), (7,), (8,), (9,), (10,), (11,)]
    """
    it = iter(it)
    return zip(*([it]*n))

def Outer(f, *lists):
    """
    >>> Outer(f, range(1,3), range(2,7,2))
    [[f(1, 2), f(1, 4), f(1, 6)], [f(2, 2), f(2, 4), f(2, 6)]]
    """
    result = [f(*args) for args in  explode(lists)]
    for l in lists[:0:-1]:
        result = [list(v) for v in groupsOfN(result, len(l))]
    return result

def _test():
    global f
    class f:
        def __init__(self, *args):
            self.args = args
        def __repr__(self):
            if len(self.args) == 1:
                return "%s(%r)" % (self.__class__.__name__.split('.')[-1], self.args[0])
            else:
                return "%s%r" % (self.__class__.__name__.split('.')[-1], self.args)

    import doctest
    doctest.testmod()

if __name__ == "__main__":
    _test()
------------------------------------------



More information about the Python-list mailing list