2012-10-22 9 views
24

Quale delle seguenti affermazioni se è più Pythonic?La legge di De Morgan è Pythonic?

if not a and not b: 
    do_something 

O

if not (a or b): 
    do something 

La sua logica non predicati quindi dovrei usare le parole chiave di Python perché è proprio più leggibile?

Nella soluzione successiva più ottimale rispetto all'altra? (Non ci credo.)

Esistono guide PEP-8 su questo?

codice Byte dei due approcci (se è importante):

In [43]: def func1(): 
    if not a and not b: 
     return 
    ....:  
    ....:  

In [46]: def func2(): 
    if not(a or b): 
     return 
    ....:  
    ....:  

In [49]: dis.dis(func1) 
    2   0 LOAD_GLOBAL    0 (a) 
       3 UNARY_NOT   
       4 JUMP_IF_FALSE   13 (to 20) 
       7 POP_TOP    
       8 LOAD_GLOBAL    1 (b) 
      11 UNARY_NOT   
      12 JUMP_IF_FALSE   5 (to 20) 
      15 POP_TOP    

    3   16 LOAD_CONST    0 (None) 
      19 RETURN_VALUE   
     >> 20 POP_TOP    
      21 LOAD_CONST    0 (None) 
      24 RETURN_VALUE   

In [50]: dis.dis(func2) 
    2   0 LOAD_GLOBAL    0 (a) 
       3 JUMP_IF_TRUE    4 (to 10) 
       6 POP_TOP    
       7 LOAD_GLOBAL    1 (b) 
     >> 10 JUMP_IF_TRUE    5 (to 18) 
      13 POP_TOP    

    3   14 LOAD_CONST    0 (None) 
      17 RETURN_VALUE   
     >> 18 POP_TOP    
      19 LOAD_CONST    0 (None) 
      22 RETURN_VALUE   
+0

Cosa intendi con le parole chiave Python? Stai usando le parole chiave Python in entrambi i casi. – sepp2k

+0

Scuse Intendevo la sintassi not(). Nel mio caso alcune cose sembreranno peggiori se non uso la sintassi (a o b). Quindi mi sto appoggiando più verso il primo frammento di codice – nialloc

+0

Tendo a pensare che 'do_qualcosa' e 'fare qualcosa' (senza sottolineatura) potrebbero essere diversi – Uri

risposta

15

direi che a seconda di quale è più facile per voi a leggere, a seconda di ciò a e b sono.

+0

Ci viene chiesto di modificare molto codice perché qualcuno ritiene che quest'ultimo sia più leggibile. Il suo Python 2.6 consente di utilizzare tutte le funzioni per istruzioni più complesse, ma quando si confrontano due elementi è importante. Penso che il primo sia più facile, ma non ho motivo di dire che l'altro non lo è. . . Un sacco di modifiche al codice e test unitario da eseguire !! – nialloc

+0

un sacco di volte cose come questa è più preferibile; o a volte è necessario seguire le convenzioni già in atto. se stai lavorando su una base di codice condivisa, e alcune persone preferiscono l'una sull'altra, andrei con la convention. rende il codice base generale molto più coerente. –

1

Sono equivalenti e se uno è più veloce dell'altro dipende dalle circostanze (i valori di aeb).

Quindi basta scegliere la versione che si trova più leggibile e/o comprensibile.

3

Quale usare? Qualunque sia più leggibile per ciò che stai cercando di fare.

Per quanto è più efficiente, il primo fa un extra not quindi è tecnicamente meno efficiente, ma non così si potrebbe notare in una situazione normale.

+0

Vuoi dire che è tecnicamente * più * efficiente. – mgilson

+0

Vuoi dire che il primo fa un extra 'not', giusto? – sepp2k

+0

Sì, su questo schermo portatile non riesco a vedere la domanda e la mia risposta in una volta. L'ho riparato. :-) – kindall

15

Penso che entrambe le vostre esempi sono ugualmente leggibili, se volevo "spingere la barca" sulla leggibilità vorrei andare con:

not any((a, b)) 

Dal momento che per me questo si legge molto di più come l'inglese, e quindi è il più Pythonic.

+0

Huh. +1 per sorprendermi - non penso di aver mai usato questo modello nel mio codice, e non riesco a spiegare il perché. È vero che io tendo ad evitare '((' 'and')) 'dove posso, ma qui non è male. – DSM

+9

Questo, tuttavia, valuterà completamente sia 'a' che' b', che i normali operatori booleani non faranno. Non una ragione per non usarlo, ma qualcosa di cui essere consapevole. – kindall

+0

@kindall buon punto! –

1

personalmente come l'approccio Eiffel, messo in forma pythonic

se a e poi b: dosomething

se a e b: dosomething

Il primo approccio differisce dalla seconda se a è falso Non valuta b nel primo caso, nel secondo lo fa.

Il o equivalente è "oppure"

http://en.wikipedia.org/wiki/Short-circuit_evaluation

e/o sono desiderosi.

e poi/oppure corto circuito la valutazione

La cosa bella di sintassi è che si legge bene, e non introduce nuove parole chiave.

+0

In Python, è possibile ottenere lo stesso effetto degli operatori "desiderosi" aggiungendo o moltiplicando le booleane. per esempio. 'bool (a) + bool (b)' è un 'eager' 'o' (valuta sempre sia' a' che 'b') e' bool (a) * bool (b) 'è" eager "' e' . Naturalmente, il solito 'and' and' or' corto circuito. – kindall

0

Per un pezzo di codice per essere Pythonic, deve essere sia piacevole per il lettore di per sé (leggibile) e nel contesto dei suoi dintorni (coerente). Senza avere il contesto di questo pezzo di codice, è difficile dare una buona opinione.

Ma, d'altra parte ... Se io fossi stato Pythonic a mio parere dando che avrei bisogno di operare coerentemente con ciò che mi circonda, che sembra non prendere in considerazione il contesto (ad esempio il PO).

Quello superiore.