2

Let's say I wanted to get all the possible combinations of three binary digits, i.e:

0,0,0
0,0,1
0,1,0
0,1,1
1,0,0
1,0,1
1,1,0
1,1,1

I could do something like this:

p = []
for a in range(2):
    for b in range(2):
        for c in range(2):
           p.append([a,b,c])

print p

But what if I wanted to define a function that returns the possiblities for n numbers of binary digits? i.e. How can I stack the for loops dynamically?

Alex Coplan
  • 13,211
  • 19
  • 77
  • 138

4 Answers4

5
from itertools import product
product(range(2), repeat=3)
Danra
  • 9,546
  • 5
  • 59
  • 117
4

Take a look at itertools.product.

Roman Bodnarchuk
  • 29,461
  • 12
  • 59
  • 75
2

No itertools solution.

def binarydigits(n):
    if n == 1:
        yield (0,)
        yield (1,)
    else:
        for i in binarydigits(n-1):
            for j in binarydigits(1):
                yield i+j
hoge
  • 320
  • 3
  • 3
  • In general, I would prefer an `itertools`-based solution to a recursive generator. – senderle Feb 09 '12 at 22:05
  • For fun: `bd = lambda n: iter(((0,),(1,))) if n == 1 else (i+j for i in bd(n-1) for j in bd(1))`. (I like to write recursive lambdas even though they aren't practical, don't ask me why). – Andrew Clark Feb 09 '12 at 22:38
2

You really only need one loop for your specific case, since the sequence of 0s and 1s you want represents successive integers:

def allbinary(ndigits):
    for n in xrange(2 ** ndigits):
        yield map(int, bin(n)[2:].zfill(ndigits))

for x in allbinary(8): print x

Note that map() produces a list rather than a tuple, but you could just convert it to a tuple if you need that specifically.

However, itertools.product as recommended by others is a better solution in most cases, including this one.

kindall
  • 178,883
  • 35
  • 278
  • 309