【问题标题】:python build a dynamic growing truth tablepython构建一个动态增长的真值表
【发布时间】:2011-09-14 06:02:50
【问题描述】:

我的问题很简单: “如何用优雅的方式在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为参数并建立表格的函数,没有必要 打印表格,返回代表表格的数据结构也可以。

【问题讨论】:

    标签: python logic truthtable


    【解决方案1】:

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

    【讨论】:

    • 这确实是他们要走的路。谢谢大家的回答。我会像这里描述的那样做,但是这里的实现值得一看和投票!
    【解决方案2】:

    当然,列表推导更加 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] )
    

    【讨论】:

    • 使用yield会是什么样子?我是 python 的新手。
    【解决方案3】:

    itertools 确实是大家指出的路。但是,如果您真的想了解此所需算法的具体细节,您应该查找recursive descent。以下是它在您的情况下的工作方式:

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

    测试,工作

    希望对你有帮助

    【讨论】:

    • 你能给我一个使用yield的版本吗?对于进一步的问题将非常有帮助:) 我非常喜欢 scala 中的产量;)
    【解决方案4】:

    看看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)]
    

    【讨论】:

      【解决方案5】:

      谁喜欢原始的 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% 测试和工作。
      (无法复制/粘贴结果或以上代码,因为我正在打电话上网)

      【讨论】:

      • 提示:如果您想要类似 yield 的功能,只需将所有括号(除了 else 之后)替换为括号,然后 lambda 函数将返回一个双生成器对象。
      【解决方案6】:

      返回代表表的数据结构就可以了

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

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

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

      【讨论】:

        【解决方案7】:

        简单的数学方法:

        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]
        

        【讨论】:

        • 这不是一个概括,它只适用于n = 3
        • 给你,现在试试
        【解决方案8】:

        这是一个使用函数式编程的实现,不使用循环,也不导入任何外部库:

        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,了解我的充实项目,用于从布尔表达式字符串生成真值表。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-04-03
          • 1970-01-01
          • 2013-11-23
          • 1970-01-01
          • 2014-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多