我的问题很简单: “如何以优雅的方式在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作为参数并构建表,这是没有必要的 要打印表,返回表示表的数据结构也没关系。
答案 0 :(得分:37)
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)]
答案 1 :(得分:5)
itertools
真的是要走的路。但是如果你真的想看到这需要的算法的细节,你应该查找recursive descent。以下是它在您的情况下的工作方式:
def tablize(n, truths=[]):
if not n:
print truths
else:
for i in [True, False]:
tablize(n-1, truths+[i])
经过测试,正常工作
希望这有帮助
答案 2 :(得分:5)
列表理解当然更像是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] )
答案 3 :(得分: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)]
答案 4 :(得分:2)
返回表示该表的数据结构很好
......在这种情况下range(2 ** n)
就是您所需要的。范围中的每个数字代表真值表中的一行。当且仅当i
变量在表的k
行中为真时,数字i
的二进制表示的k
位为1。 / p>
如果你想要一个真正的桌子,你可以使用:
[ [ ((row >> bit_index) & 1) == 1 for bit_index in range(n)]
for bit_index in range(2 ** n) ]
答案 5 :(得分:1)
简单的数学方法:
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]
答案 6 :(得分:0)
谁喜欢原始的1-liners?
>>> 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%测试和工作。
(不能复制/粘贴结果,或者上面的代码,导致我在手机上用于互联网)
答案 7 :(得分: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 repo 以查看我用于从布尔表达式字符串生成真值表的充实项目。