2011-06-13 55 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