Generating multiple lists from one list

Anand anand.chittu at gmail.com
Wed Jul 5 22:56:26 EDT 2006


> p_code = ''
> for i,k in enumerate(ks):
>     p_code += i*' ' + "for item%s in elts['%s']:\n" %(i,k)
> p_code += len(ks)*' '+'print ['+','.join([ "item%s" %i
>     for i,k in enumerate(ks) ])+']'
>
> # print the code
> print p_code
>
> >for item0 in elts['a']:
> > for item1 in elts['b']:
> >  for item2 in elts['c']:
> >   for item3 in elts['d']:
> >    print [item0,item1,item2,item3]
>
> # execute this code
> exec p_code

This is not very nice. you can use recursion instead of generating
code.

The following solution first divides the given list into groups based
on the first token and computes their cross product using recursion.

def get_groups(x):
    """Groups the elements of the list x using the first token of the
elment.
    All elements are expected of the form "a.n".
    for example:
        >>> get_groups(["a.1", "b.2", "a.2"])
        [["a.1", "a.2"], ["b.1"]]
    """
    groups = {}

    for item in x:
        a, n = item.split('.')

        if a not in groups:
            groups[a] = []

        groups[a].append(item)

    keys = groups.keys()
    keys.sort()

    return [groups[k] for k in keys]

def cross_product(items):
    """
    computes cross product of the list of lists.
    example:
        >>> cross_product([["a", "b"], ["c"]])
        [["a", "b"], ["a", "c"]]
    """
    if not items:
        return [[]]

    x = items[-1]
    result = cross_product(items[:-1])

    return [a + [b] for a in result for b in x]


x = ['a.1','b.3','b.4','c.2','c.6','d.3']

print cross_product(get_groups(x))




More information about the Python-list mailing list