2013-05-06 3 views
9

Mi piacerebbe scrivere una dichiarazione in python con implicazioni logiche. Qualcosa di simile:Esiste un operatore logico implicito in python?

if x => y: 
    do_sth() 

Naturalmente, so che potrei usare:

if (x and y) or not x: 
    do_sth() 

Ma c'è un operatore logico per questo in Python?

risposta

15

p => q è lo stesso di not(p) or q, quindi puoi provarlo!

+0

e che è più semplice di quanto (x ed y) o non x. Grazie –

+5

Il TTL è d'accordo - ma non è necessariamente così facile da vedere nel codice, anche se più semplice dell'originale. Una funzione - ad esempio 'implica x, y)' - potrebbe essere di aiuto nel trasferire l'idea di più, se tale costrutto si verifica abbastanza spesso da giustificare un nome. – user2246674

+5

@ user2246674 D'accordo, raccomanderei di fare di questa funzione una chiarezza. –

5

La tua domanda chiede se esiste un singolo operatore logico per questo in Python, la semplice risposta è no: The docs elenca le operazioni booleane, e Python semplicemente non ha nulla di simile.

Ovviamente, come sottolinea Juampi's answer, ci sono operazioni logicamente equivalenti che sono un po 'più brevi, ma non ci sono operatori singoli come richiesto.

+0

Si prega di dare un'occhiata a [questo] (http://stackoverflow.com/questions/16405892/is-there-an-implication-logical-operator-in-python/33768787#33768787) risposta. Sembra che non tutto possa essere trovato in [docs] (http://docs.python.org/3.3/reference/expressions.html#boolean-operations). –

+0

@ running.t Non è presente nei documenti perché quella risposta è sbagliata - non esiste un operatore del genere, invece, è un abuso di un altro operatore che produce lo stesso risultato. Il risultato finale dell'uso sarebbe un codice orribilmente poco chiaro e inefficiente che potrebbe introdurre bug. –

1

Ulteriori dettagli basati su ciò che ho trovato qui e là come stavo cercando un operatore implicito: è possibile utilizzare un trucco intelligente per definire i propri operatori. Ecco un esempio in esecuzione annotato con le fonti che mi portano a questo risultato.

#!/usr/bin/python 

# From http://code.activestate.com/recipes/384122/ (via http://stackoverflow.com/questions/932328/python-defining-my-own-operators) 
class Infix: 
    def __init__(self, function): 
     self.function = function 
    def __ror__(self, other): 
     return Infix(lambda x, self=self, other=other: self.function(other, x)) 
    def __rlshift__(self, other): 
     return Infix(lambda x, self=self, other=other: self.function(other, x)) 
    def __or__(self, other): 
     return self.function(other) 
    def __rshift__(self, other): 
     return self.function(other) 
    def __call__(self, value1, value2): 
     return self.function(value1, value2) 

from itertools import product 

booleans = [False,True] 

# http://stackoverflow.com/questions/16405892/is-there-an-implication-logical-operator-in-python 
# http://jacob.jkrall.net/lost-operator/ 
operators=[ 
    (Infix(lambda p,q: False),     "F"), 
    (Infix(lambda p,q: True),     "T"), 
    (Infix(lambda p,q: p and q),    "&"), 
    (Infix(lambda p,q: p or q)   ,  "V"), 
    (Infix(lambda p,q: p != q)   ,  "^"), 
    (Infix(lambda p,q: ((not p) or not q)),  "nad"), 
    (Infix(lambda p,q: ((not p) and not q)), "nor"), 
    (Infix(lambda p,q: ((not p) or q)),   "=>"), 
    ] 

for op,sym in operators: 
    print "\nTruth tables for %s" % sym 

    print "\np\tq\tp %s q\tq %s p" % (sym,sym) 
    for p,q in product(booleans,repeat=2): 
     print "%d\t%d\t%d\t%d" % (p,q,p |op| q,q |op| p) 

    print "\np\tq\tr\tp %s q\tq %s r\t(p %s q) %s r\tp %s (q %s r)\tp %s q %s r" % (sym,sym,sym,sym,sym,sym,sym,sym) 
    for p,q,r in product(booleans,repeat=3): 
     print "%d\t%d\t%d\t%d\t%d\t%d\t\t%d\t\t%d" % (p,q,r,p |op| q,q |op| r, (p |op| q) |op| r, p |op| (q |op| r), p |op| q |op| r) 
     assert((p |op| q) |op| r == p |op| q |op| r) 
4

Solo perché è divertente: x => y potrebbe essere bool(x) <= bool(y) in python.

+3

E questa è (finalmente) la prova conclusiva che 'True' dovrebbe essere' -1' e 'False' dovrebbe essere' 0' per i booleani! (Invece dell'attuale convenzione Python di 'True == 1'.) Perché allora avremmo' x => y' matching 'y <= x' (che sembra un'implicazione da destra a sinistra) per i booleani. –

1

V'è un conversare operatore di implicazione:

if y ** x: 
    do_sth() 

Questo si legge: se y è implicito x.

crediti verso https://github.com/cosmologicon/pywat

+0

Sì. Questo e 'esattamente quello che stavo cercando. E sembra che questa implicazione inversa non sia documentata, quindi la risposta di @Latty è fondamentalmente errata. –

+1

@running.t Questo è qualcosa che ha lo stesso effetto di 'x => y', ma non è un operatore per quello scopo. Questo è l'operatore di potenza, e non è un operatore logico, ma uno numerico. Non restituisce 'True' o' False', ma un numero. Questo è più lento e potrebbe potenzialmente introdurre bug, per non parlare di essere incredibilmente poco chiari e difficili da leggere. Raccomanderei * altamente * di non farlo mai, e invece userei 'not (p) o q' come da [risposta di Juampi] (http://stackoverflow.com/a/16405931/722121). –

0

Direi un più leggibile one-liner sarebbero

x_implies_y = y if x else True 

Nel tuo esempio originale:

if (y if x else True): do_sth()