[Tutor] Question on lists

A.M. Kuchling amk at amk.ca
Sun Sep 14 13:04:22 EDT 2003


On Sun, Sep 14, 2003 at 07:22:10PM -0400, John Miller wrote:
>are properly indented? Is this a case where you need to use something  
>like 'exec'? Hmmm, (coding out loud):

Generating code is usually pretty complicated.  It would be possible
to make it work, but it would be hard to debug.

It's easier to solve the problem recursively.  A full solution is
below.  Here's how it's derived.

I want a function generate(list1, list2, list3, ...) that outputs 
an iterator that produces all the possible combination.  That gives me the 
prototype:

def generate (*lists):

When there are no arguments, the job is easy; there are no combinations
to return at all:

    # No lists to generate from, so don't yield anything.
    if len(lists) == 0:
        return

If there's a single list, it's also easy; just loop over the list and
return a list of every element.

    # One list, so loop over each element 
    elif len(lists) == 1:
        for item in lists[0]:
            yield [item]

If there's more than one list, we take the first list and loop over
its elements, and call generate() with the rest of the lists.  

    first_list = lists[0]
    for item in first_list:
        for output in generate(*lists[1:]):
            yield [item] + output
    
And that's it.            

--amk

def generate (*lists):
    # No lists to generate from, so don't yield anything.
    if len(lists) == 0:
        return

    # One list, so loop over each element 
    elif len(lists) == 1:
        for item in lists[0]:
            yield [item]
            
    first_list = lists[0]
    for item in first_list:
        for output in generate(*lists[1:]):
            yield [item] + output
    

for item in generate ([1,2,3]):
    print item

for item in generate ([1,2,3], ['a', 'b'], ['c', 'd']):
    print item




More information about the Tutor mailing list