# Creating unique combinations from lists

Tim Chase python.list at tim.thechases.com
Wed Jan 16 21:40:07 CET 2008

```> a = ['big', 'small', 'medium'];
> b = ['old', 'new'];
> c = ['blue', 'green'];
>
> I want to take those and end up with all of the combinations they
> create like the following lists
> ['big', 'old', 'blue']
> ['small', 'old', 'blue']
> ['medium', 'old', 'blue']
> ['big', 'old', 'green']
> ['small', 'old', 'green']
> ['medium', 'small', 'green']
> ['big', 'new', 'blue']
> ['small', 'new', 'blue']
> ['medium', 'new', 'blue']
> ['big', 'new', 'green']
> ['small', 'new', 'green']
> ['medium', 'new', 'green' ]
>
> I could do nested for ... in loops, but was looking for a Pythonic way
> to do this.  Ideas?

You can use a recursive generator:

def iterall(*iterables):
if iterables:
for remainder in iterall(*iterables[1:]):
else:
yield []

for thing in iterall(
['big', 'medium', 'small'],
['old', 'new'],
['blue', 'green'],
):
print thing

The two for-loops plus recursion should handle any number of
parameters, so if you were so inclined, you could do

for thing in iterall(
['big', 'medium', 'small'],
['old', 'new'],
['blue', 'green'],
['smelly', 'fragrant'],
):
print thing

and get all 3*2*2*2*2 items.  Or count in binary:

for i, bitstream in enumerate(iterall(
[0, 1],
[0, 1],
[0, 1],
[0, 1],
[0, 1],
[0, 1],
)):
print ''.join(map(str, bitstream)), '=', i

When you're iterating over combinations of items in groups of
lists, I prefer the clarity of this over something like

[(a,b,c,d,e) for a in [0,1] for b in [0,1] for c in [0,1] for
d in [0,1] for e in [0,1]]

-tkc

```