[Tutor] Question on lists

Raymond Hettinger python at rcn.com
Sun Sep 14 21:01:16 EDT 2003


[james roy]
> > I am new to programming with python. I dont know I am having my  
> > problem like this:
> > I am having a few lists that i know in no dynamically.
> > For example:
> > List1 = ['1','2','3']
> > List2 = ['/']
> > List3 = ['4','5','6']
> > I want to make the combinations like this:
> >
> > '1' / '4'
> > '1' / '5'
> > '1' / '6'
> > '2' / '4'
> > '2' / '5'
> > '2' / '6'
> > '3' / '4'
> > '3' / '5'
> > '3' / '6'
> >
> > I want to genearlise this as:
> > I can have 'n' no of elements in 'N' no of lists and i want to make  
> > the combinations like i have written.

[John Miller]
> I found this to be an intriguing problem. I, too, am having trouble  
> generalizing a solution. *IF* I know ahead of time how many lists there  
> will be, I can simply nest a bunch of for loops like so:
> 
> '''
> all_lists=[['a','b','c'],['*','/'],[1,2,3,4,5],['+','- 
> '],['w','x','y','z']]
> P = [] #all the resulting permutations
> for h in all_lists[0]:
>      for i in all_lists[1]:
>          for j in all_lists[2]:
>              for k in all_lists[3]:
>                  for l in all_lists[4]:
>                      P.append((h,i,j,k,l))
> print P
> '''
> 
> But the question was 'N' number of lists. Can I somehow count the  
> number of lists and use that to construct on the fly 'N' for loops that  
> are properly indented? Is this a case where you need to use something  
> like 'exec'? Hmmm, (coding out loud):
> 
> '''
> all_lists=[['a','b','c'],['*','/'],[1,2,3,4,5],['+','- 
> '],['w','x','y','z']]
> #this 'var_dict' is cheating; I'm assuming a number of variables to  
> cover
> #the largest possible number of lists could be constructed;
> #other approaches?
> var_dict = {0:'h',1:'i',2:'j',3:'k',4:'l'}
> codelines = {} #a dictionary of lines of code keyed by 'line number'
> j = 0 #to keep track of the number of lines to add the final line  
> outside the loop
> P = [] #all the resulting permutations
> for i in range(len(all_lists)):
>      codelines[i] = '%sfor %s in all_lists[%s]:' % ('    ' * i,  
> var_dict[i], i)
>      j += 1
> codelines[j]='%sP.append((h,i,j,k,l))' % ('    ' * j)
> codestrings = []
> for k in range(len(codelines)):
>      codestrings.append(codelines[k])
> code = '\n'.join(codestrings)
> exec code
> print P
> '''
> The problem is, this doesn't quite work (although I think it's close).


This can be made *much* simpler.


def product(*args):
    'Compute the cartesian product of the sequence arguments'
    if args == ():
        return [[]]
    subproblem = prod(*(args[1:]))
    return [[elem]+tail for elem in args[0] for tail in subproblem]
           
List1 = ['1','2','3']
List2 = ['/']
List3 = ['4','5','6']

for group in product(List1, List2, List3):
    print ''.join(group)



More information about the Tutor mailing list