20

私の質問は単純です:「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をパラメータとしてテーブルを作成する関数が欲しいのですが、テーブルを印刷する必要はなく、テーブルを表すデータ構造を返すこともできます。

4

8 に答える 8

46

使用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)]
于 2011-06-13T21:14:10.203 に答える
6

もちろん、リスト内包表記はより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] )
于 2011-06-13T21:35:40.067 に答える
5

itertoolsみんなが指摘しているように、本当に行く道です。しかし、これに必要なアルゴリズムの要点を本当に知りたい場合は、再帰下降を調べる必要があります。これがあなたの場合にどのように機能するかです:

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

テスト済み、動作中

お役に立てれば

于 2011-06-13T21:27:55.017 に答える
2

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)]
于 2011-06-13T21:17:53.807 に答える
2

テーブルを表すデータ構造を返すことは問題ありません

...その場合、range(2 ** n)必要なのはそれだけです。範囲内の各数値は、真理値表の行を表します。数値の2進表現のithビットは、テーブルのth行でth変数がtrueであるk場合に限り、1です。ik

実際のテーブルが必要な場合は、次を使用できます。

[ [ ((row >> bit_index) & 1) == 1 for bit_index in range(n)] 
  for bit_index in range(2 ** n) ]
于 2011-06-14T01:58:18.587 に答える
2

ここで生の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%テストされ、動作しています。
(結果、または上記のコードをコピー/貼り付けできないため、インターネット用の電話を使用しています)

于 2017-04-23T01:56:37.143 に答える
2

簡単な数学のアプローチ:

a = lambda x: [x//4%2,x//2%2,x%2]

for i in range(8):
    print(a(i))

[0, 0, 0]
[0, 0, 1]
[0, 1, 0]
[0, 1, 1]
[1, 0, 0]
[1, 0, 1]
[1, 1, 0]
[1, 1, 1]

編集:

より一般的な形式は次のとおりです。

def truth_table(n):
    for i in range(2**n):
        line = [i//2**j%2 for j in reversed(range(n))]
        print(line)

これにより、結果は次のようにのみ出力されます。

>>> truth_table(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]
于 2020-02-03T20:58:17.757 に答える
0

関数型プログラミングを使用し、ループを使用せず、外部ライブラリをインポートしない実装を次に示します。

get_bits = lambda n: [*map(lambda x:[*map(int,bin(x)[2:].zfill(n))],range(2**n))]

get_bits次に、必要な数のパラメーターを使用して呼び出します。

>>> get_bits(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]]

私のGitHubリポジトリをチェックして、ブール式の文字列から真理値表を生成するための具体的なプロジェクトを確認してください。

于 2021-04-30T06:53:31.497 に答える