2011-06-13 50 views
15

我的问题很简单: “如何在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作为参数并建立该表中,没有必要 要打印表格,返回表示表格的数据结构也是好的。

回答

33

使用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)] 
+3

这很漂亮。 – Nobita 2011-06-13 21:15:49

+0

这是他们确实走的路。谢谢大家的答案。我会像这里描述的那样去做,但是这里的实现值得关注并投票! – evildead 2011-06-13 22:36:38

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

itertools真的是去为已经指明了方向大家都出去了。但是如果你真的想看到这个算法所需的算法,你应该查找recursive descent。下面是它如何工作你的情况:

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

测试工作

希望这有助于

+0

美丽,谢谢! – evildead 2011-06-13 22:35:08

+0

你能给我一个使用yield的版本吗?将会对进一步的问题非常有用:)我喜欢scala的良率;) – evildead 2011-06-13 22:38:34

+0

如果您将'print'更改为'yield',它应该可以正常工作 – inspectorG4dget 2011-06-14 13:31:30

4

列表理解,当然,更P​​ython。

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]) 
+0

使用yield的效果如何?我在Python中有点新鲜。 – evildead 2011-06-13 22:37:30

2

返回代表表中的数据结构是好的

...在这种情况下range(2 ** n)是你所需要的。范围中的每个数字表示真值表中的一行。 k的二进制表示形式的i第1位是1,当且仅当表的k行中的ith变量为真时。

如果你想要一个实际的表,你可以使用:

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

谁喜欢这里生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%测试和工作。
(无法复制/粘贴结果,或以上代码,导致我在互联网电话上)

+0

提示:如果您想要类似yield的功能,只需用括号替换所有括号(除了else之外),lambda函数就会返回一个双重生成器对象。 – Tcll 2017-04-23 02:15:14