Python создает динамически растущую таблицу истинности

Мой вопрос прост: "Как построить динамически растущую таблицу истинности в python в элегантном стиле?"

при 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))

при 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))

Я хотел бы иметь функцию, которая принимает n в качестве параметра и создает таблицу, это не обязательно чтобы распечатать таблицу, также хорошо восстановить структуру данных, представляющую таблицу.

Ответы

Ответ 1

Используйте itertools.product():

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

Результат для 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)]

Ответ 2

itertools действительно есть способ пойти, как было указано всеми. Но если вы действительно хотите увидеть необходимые для этого гайки и болты алгоритма, вы должны искать рекурсивный спуск. Вот как это будет работать в вашем случае:

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

Протестировано, работает

Надеюсь, что это поможет

Ответ 3

Список понятий, конечно, больше Pythonic.

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

Результаты, отступы для 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] ]

Как функция-генератор с 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]

Также простое изменение возврата от понимания массива к выражению генератора делает возвращаемый тип эквивалентным функции генерации версии yield:

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

Ответ 4

Посмотрите itertools модуль

In [7]: [i for i in itertools.product([0,1], repeat=3)]
Out[7]: 
[(0, 0, 0),
 (0, 0, 1),
 (0, 1, 0),
 (0, 1, 1),
 (1, 0, 0),
 (1, 0, 1),
 (1, 1, 0),
 (1, 1, 1)]

Ответ 5

возвращает структуру данных, представляющую таблицу, в порядке

... в этом случае range(2 ** n) - это все, что вам нужно. Каждое число в диапазоне представляет строку в таблице истинности. i -ый бит двоичного представления числа k равен 1 тогда и только тогда, когда переменная i th истинна в k -й строке таблицы.

Если вы хотите использовать фактическую таблицу, которую вы можете использовать:

[ [ ((row >> bit_index) & 1) == 1 for bit_index in range(n)] 
  for bit_index in range(2 ** n) ]

Ответ 6

кто здесь любит сырые 1-лайнеры?

>>> truthtable = lambda n: [[(v>>i)&1 for i in range(n-1,-1,-1)] for v in range(1<<n)] if n>0 else [[]]

100% проверено и работает.
(не удается скопировать/вставить результат или код выше, потому что я нахожусь на телефоне для Интернета)