Python создает динамически растущую таблицу истинности - PullRequest
17 голосов
/ 14 июня 2011

Мой вопрос прост: «Как изящно построить динамически растущую таблицу истинности в 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 в качестве параметра и формирует таблицу, нет необходимости печатать таблицу, возвращая структуру данных, представляющую таблицу, также хорошо.

Ответы [ 6 ]

37 голосов
/ 14 июня 2011

Использование 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)]
5 голосов
/ 14 июня 2011

Понимание списка, конечно, более Pythonic.

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

Результаты с отступом для ясности:

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] )
5 голосов
/ 14 июня 2011

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

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

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

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

2 голосов
/ 14 июня 2011

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

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

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

[ [ ((row >> bit_index) & 1) == 1 for bit_index in range(n)] 
  for bit_index in range(2 ** n) ]
2 голосов
/ 14 июня 2011

Посмотрите на модуль 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)]
0 голосов
/ 23 апреля 2017

кто здесь любит сырые 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% проверено и работает.
(невозможно скопировать / вставить результат или код выше, потому что я нахожусь на телефоне для Интернета)

...