# [Chicago] Printing out the Cartesian product.

Jeremy McMillan jeremy.mcmillan at gmail.com
Thu Jul 16 19:55:46 CEST 2015

```Doug:

http://mathworld.wolfram.com/CartesianProduct.html <-- sets!

The cartesian product of ("A","T","C","G") doesn't make sense.

What you meant was the cartesian product of
[{"A","T","C","G"}, {"A","T","C","G"}, {"A","T","C","G"}, {"A","T","C","G"}]

which is exactly what the repeat=4 argument to itertools.product() means.

Each of the four nucleotides' sets is distinct in each position of the list
of sets. Since each set is identical, we are explicitly saying each of the
nucleotides can be in any position of the lists in our product.

What itertools.product() sees is more like this appears to human eyes:
[{"A1","T1","C1","G1"}, {"A2","T2","C2","G2"}, {"A3","T3","C3","G3"},
{"A4","T4","C4","G4"}]

I haven't looked (encapsulation!), but I would expect to see something very
much like Carl wrote, implemented as a generator, in the source for
itertools.product().

On Wed, Jul 15, 2015 at 9:48 PM, Carl Karsten <carl at personnelware.com>
wrote:

> Your example looks to me similar to counting to 4^4 in base 4, only shift
> the digits by 1.
>
> in base 10, we use the following 10 symbols:
> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
>
> in base 4, we use the following 4 symbols:
> 0, 1, 2, 3
>
> base 2
> 0,1
>
> going back to base 4, but shifted...
> 1, 2, 3, 4
>
> def lcBaseX( val, alphabet ):
>     size = len( alphabet )
>     ret = ''
>     for i in range(size):
>         dig = val % size
>         val = int( val/size )
>         dig = alphabet[dig]
>         ret = dig + ret
>     return ret
>
> # hard coded for 3 so it is a little more obvious
> for i in range(3**3):
>     print i, lcBaseX(i,["0", "1", "2"]), lcBaseX(i, ["1", "2", "3"])
>
> x=4
> for i in range(x**x):
>     print i,
>     print lcBaseX(i,[str(a) for a in range(x)]),
>     print lcBaseX(i,[str(a) for a in range(1,x+1)])
>
> x can be anything.  over 10 and you will want to add some spaces between
> the digits.
> ret = dig + " " + ret
>
>
>
> On Wed, Jul 15, 2015 at 5:15 PM, Lewit, Douglas <d-lewit at neiu.edu> wrote:
>
>> Hi everyone,
>>
>> I need some advice on how to do something.  Let's say that I want to
>> print out the Cartesian product of the integers 1 to 4.  It would look
>> something like this:
>>
>> 1, 1, 1, 1
>> 1, 1, 1, 2
>> 1, 1, 1, 3
>> 1, 1, 1, 4
>> 1, 1, 2, 1
>> 1, 1, 2, 2
>> 1, 1, 2, 3
>> 1, 1, 2, 4
>> 1, 1, 3, 1
>> 1, 1, 3, 2
>> 1, 1, 3, 3, etc, etc until finally we have
>> ..............
>> 4, 4, 4, 3
>> 4, 4, 4, 4
>>
>> This is NOT a permutation because repetition is allowed.  Nor is it a
>> combination because for example 1, 1, 1, 2 is distinct from 2, 1, 1, 1.  I
>> believe this is technically called a Cartesian product.
>>
>> I know of two ways to do this:
>>
>> Method #1:
>>
>> *for a in range(1, 5):*
>> *     for b in range(1, 5):*
>> *          for c in range(1, 5):*
>> *                for d in range(1, 5):*
>> *                      print( a, end = ", " )*
>> *                      print( b, end = ", " )*
>> *                      print( c, end = ", " )*
>> *                      print( d, end = "\n" )*
>>
>>
>> The above works just fine!  But there's a problem.  What if let's say I
>> want the Cartesian product of all the integers from 1 to 10?  That means
>> working with 10 nested for-loops!  That's insane!  It's tedious to write
>> and probably even worse for the person who is reading it.  So this method
>> is limited to smaller examples.
>>
>> Method #2:
>>
>> Cheat by using Python's itertools package!  (Or is it a library?  What's
>> the difference between a package and a library?)
>>
>> import itertools
>>
>> carProduct = itertools.product([1, 2, 3, 4], repeat = 4)
>>
>> *try:*
>> *     while True:*
>> *               print( next(carProduct) )*
>> *except StopIteration:*
>> *      pass*
>>
>> This method is short and sweet!  It works great!  But it's really
>> cheating in the sense that the programmer is taking advantage of code that
>> has already been written.  (I have nothing against doing that!  But in a CS
>> class if I write down that answer on an exam do you think the professor is
>> going to give me any credit?  Probably not!!!  LOL! )
>>
>> Is there some other way?  I'm guessing that I would need a for-loop that
>> contains a recursive function.  Or.... maybe a recursive function that
>> contains a for-loop?  I really don't know.  I've been struggling with this
>> for a couple days now and I can't think of a solution.  Can someone please
>> enlighten me?
>>
>> Gratefully,
>>
>> Douglas.
>>
>>
>> _______________________________________________
>> Chicago mailing list
>> Chicago at python.org
>> https://mail.python.org/mailman/listinfo/chicago
>>
>>
>
>
> --
> Carl K
>
>
> _______________________________________________
> Chicago mailing list
> Chicago at python.org
> https://mail.python.org/mailman/listinfo/chicago
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/chicago/attachments/20150716/ccdd6c3b/attachment.html>
```