Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python build a dynamic growing truth table

My question is simple: "how to build a dynamic growing truth table in python in an elegant way?"

for n=3

for p in False, True:
    for q in False, True:
        for r in False, True:
            print '|{0} | {1} | {2} |'.format(int(p),int(q), int(r))

for n=4

for p in False, True:
    for q in False, True:
        for r in False, True:
            for s in False, True:
                print '|{0} | {1} | {2} | {3}'.format(int(p),int(q), int(r), int(s))

I would like to have a function which takes n as a parameter and builds up the table, it is not necessary to print the table, returning a data structure representing the table is fine also.

like image 952
evildead Avatar asked Jun 13 '11 21:06

evildead


3 Answers

Use itertools.product():

table = list(itertools.product([False, True], repeat=n))

Result for n = 3:

[(False, False, False),
 (False, False, True),
 (False, True, False),
 (False, True, True),
 (True, False, False),
 (True, False, True),
 (True, True, False),
 (True, True, True)]
like image 158
Sven Marnach Avatar answered Nov 09 '22 04:11

Sven Marnach


List comprehensions are, of course, more Pythonic.

def truthtable (n):
  if n < 1:
    return [[]]
  subtable = truthtable(n-1)
  return [ row + [v] for row in subtable for v in [0,1] ]

Results, indented for clairity:

truthtable(1)
[ [0],
  [1] ]

truthtable(3)
[ [0, 0, 0],
  [0, 0, 1],
  [0, 1, 0],
  [0, 1, 1],
  [1, 0, 0],
  [1, 0, 1],
  [1, 1, 0],
  [1, 1, 1] ]

As a generator function with yield:

def truthtable (n): 
  if n < 1:
    yield []
    return
  subtable = truthtable(n-1)
  for row in subtable:
    for v in [0,1]:
      yield row + [v]

Also simply changing the return from an array comprehension to a generator expression makes the return type equivalent to the yield version's generator function:

def truthtable (n):
  if n < 1:
    return [[]]
  subtable = truthtable(n-1)
  return ( row + [v] for row in subtable for v in [0,1] )
like image 6
Glenn Moss Avatar answered Nov 09 '22 02:11

Glenn Moss


itertools really is the way to go as has been pointed out by everyone. But if you really want to see the nuts and bolts of the algorithm required for this, you should look up recursive descent. Here's how it would work in your case:

def tablize(n, truths=[]):
    if not n:
        print truths
    else:
        for i in [True, False]:
            tablize(n-1, truths+[i])

Tested, working

Hope this helps

like image 5
inspectorG4dget Avatar answered Nov 09 '22 03:11

inspectorG4dget