Search code examples
pythonpython-2.7python-itertools

Using itertools to generate an exponential binary space


I am interested in generating all binary combination of N variables without having to implement a manual loop of iterating N times over N and each time looping over N/2 and so on.

Do we have such functionality in python?

E.g:

I have N binary variables:

pool=['A','B','C',...,'I','J']
len(pool)=10

I would like to generate 2^10=1024 space out of these such as:

          [A B C ... I J]
iter0    = 0 0 0 ... 0 0
iter1    = 0 0 0 ... 0 1
iter2    = 0 0 0 ... 1 1
...
iter1022 = 1 1 1 ... 1 0
iter1023 = 1 1 1 ... 1 1

You see that I don't have repetitions here, each variable is enabled once per each of these iter's sequences. How can I do that using Python's itertools?


Solution

  • itertools.product with the repeat parameter is the simplest answer:

    for A, B, C, D, E, F, G, H, I, J in itertools.product((0, 1), repeat=10):
    

    The values of each variable will cycle fastest on the right, and slowest on the left, so you'll get:

    0 0 0 0 0 0 0 0 0 0
    0 0 0 0 0 0 0 0 0 1
    0 0 0 0 0 0 0 0 1 0
    0 0 0 0 0 0 0 0 1 1
    0 0 0 0 0 0 0 1 0 0
    

    etc. This may be recognizable to you: It's just the binary representation of an incrementing 10 bit number. Depending on your needs, you may actually want to just do:

    for i in range(1 << 10):
    

    then mask i with 1 << 9 to get the value of A, 1 << 8 for B, and so on down to 1 << 0 (that is, 1) for J. If the goal is just to print them, you can even get more clever, by binary stringifying and then using join to insert the separator:

    for i in range(1 << 10):
        print(' '.join('{:010b}'.format(i)))
        # Or letting print insert the separator:
        print(*'{:010b}'.format(i)) # If separator isn't space, pass sep='sepstring'