2011-06-13 9 views
15

Mi pregunta es simple: "¿cómo construir una tabla de verdad de crecimiento dinámico en python de una manera elegante?"Python construye una tabla de verdad creciente dinámica

para 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)) 

para 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)) 

me gustaría tener una función que toma n como parámetro y se acumula la mesa, no es necesario para imprimir la tabla, devolver una estructura de datos que representa la tabla también está bien.

Respuesta

33

Uso itertools.product():

table = list(itertools.product([False, True], repeat=n)) 

Resultado para 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

esto es hermoso. – Nobita

+0

este es su camino a seguir. Gracias a todos por las respuestas. Lo haré como se describe aquí, pero las implementaciones aquí abajo ¡vale la pena mirar y votar! – evildead

2

Para consultar el módulo 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 es realmente el camino a seguir como se ha señalado por todos Pero si realmente desea ver los aspectos prácticos del algoritmo requerido para esto, debe buscar recursive descent. Así es como funcionaría en su caso:

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

Probado, trabajando

Esperanza esto ayuda

+0

hermosa, gracias! – evildead

+0

¿me puede dar una versión que utiliza el rendimiento? Sería muy útil para otros problemas :) Me gusta mucho el rendimiento en scala;) – evildead

+0

Simplemente debería funcionar si cambió 'print' para' yield' – inspectorG4dget

4

Las listas por comprensión son, por supuesto, más Pythonic.

def truthtable (n): 
    if n < 1: 
    return [[]] 
    subtable = truthtable(n-1) 
    return [ row + [v] for row in subtable for v in [0,1] ] 

Resultados, indentadas para 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] ] 

Como una función de generador con 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] 

también simplemente cambiando el retorno de una matriz de comprensión para una expresión generador hace que el retorno tipo equivalente a la función de generador de la versión 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

¿cómo se vería con el rendimiento? Soy un poco nuevo en Python. – evildead

2

el retorno de una estructura de datos que representa la tabla está muy bien

... en ese caso range(2 ** n) es todo lo que necesita. Cada número en el rango representa una fila en la tabla de verdad. El i th bit de la representación binaria del número k es 1 si y solo si la variable i th es verdadera en la kª fila de la tabla.

Si desea una tabla real que puede utilizar:

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

que aquí le gusta primas 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% testedos y trabajados.
(no se puede copiar/pegar el resultado, o el código anterior, porque estoy en un teléfono para Internet)

+0

sugerencia: si desea funcionalidad tipo rendimiento, simplemente reemplace todos los corchetes (excepto después de lo demás) con paréntesis, la función lambda devolverá un objeto generador doble. – Tcll

Cuestiones relacionadas