Search code examples
pythonpython-3.xpython-itertoolscartesian-product

How to create a cartesian product excluding some results?


For my calculations, I need all 32-element cartesian products composed of 0 and 1, where there is twelve 1.

I'm currently using the following method:

for k,l in enumerate(itertools.product([0,1], repeat=32)):
        if l.count(1)==12:                                        
            # rest code

But as you can see, it is not very optimal for such a large cartesian product.

How build the list that I need without having to go through all the elements itertools.product and without an additional if condition? Is there a faster way to do this?


Solution

  • This will only generate lists of bits elements where ones are 1 and the rest are 0:

    def binLimit1s( bits, ones, prefix=[] ):
        if bits<ones:
            yield prefix
        elif ones==0:
            yield prefix + [0]*bits
        elif ones==bits:
            yield prefix + [1]*bits
        else:
            for x in binLimit1s( bits-1, ones, prefix+[0] ):
                yield x
            for x in binLimit1s( bits-1, ones-1, prefix+[1] ):
                yield x
    

    In your case, you would use

    binLimit1s( 32, 12 )