2013-07-15 13 views
31

Widziałem to w obie strony, ale która droga jest bardziej Pythonic?Co więcej "pythonic" dla "nie"

a = [1, 2, 3] 

# version 1 
if not 4 in a: 
    print 'is the not more pythonic?' 

# version 2 
if 4 not in a: 
    print 'this haz more engrish' 

Który sposób zostałby uznany za lepszy Python?

+6

Drugi, założę. – StoryTeller

+6

Drugi czyta się dobrze jako angielskie zdanie i działa tak, jak powinien. ==> przejdź do niego. – mnagel

+0

możliwy duplikat [Kolejność składni do używania słów kluczowych "nie" i "w"] (http://stackoverflow.com/questions/8738388/order-of-syntax-for-using-not-and-in- kluczowe) – Amelia

Odpowiedz

44

Drugie rozwiązanie jest bardziej pythonowy z dwóch powodów:

  • jest jeden operator, co przekłada się na jednej kodu Java argumentu. Druga linia to naprawdę not (4 in a); dwóch operatorów.

    Tak czy inaczej, Python optimizes the latter case i mimo to tłumaczy not (x in y) na x not in y, ale jest to szczegół implementacji kompilatora CPython.

  • Jest blisko tego, w jaki sposób używałbyś tej samej logiki w języku angielskim.
+5

Czy możesz umieścić to źródło? – Michael

+1

@AshwiniChaudhary: To jest optymalizacja CPython wykonana przez kompilator –

+2

@MartijnPieters Znaleziono http://hg.python.org/cpython/file/ed8b0ee1c531/Python/peephole.c#l405;) –

22

Większość zgodziłaby się, że 4 not in a jest bardziej Pythoniczny.

Python został zaprojektowany w celu łatwego zrozumienia i zrozumiałości, i brzmi bardziej jak mówisz po angielsku - prawdopodobnie nie musisz znać Pythona, aby zrozumieć, co to znaczy!

Należy zauważyć, że w odniesieniu do kodu bajtowego, dwa będą identyczne w CPython (choć not in jest technicznie jeden operator, not 4 in a podlega optymalizacji):

>>> import dis 
>>> def test1(a, n): 
     not n in a 


>>> def test2(a, n): 
     n not in a 


>>> dis.dis(test1) 
    2   0 LOAD_FAST    1 (n) 
       3 LOAD_FAST    0 (a) 
       6 COMPARE_OP    7 (not in) 
       9 POP_TOP    
      10 LOAD_CONST    0 (None) 
      13 RETURN_VALUE   
>>> dis.dis(test2) 
    2   0 LOAD_FAST    1 (n) 
       3 LOAD_FAST    0 (a) 
       6 COMPARE_OP    7 (not in) 
       9 POP_TOP    
      10 LOAD_CONST    0 (None) 
      13 RETURN_VALUE   
+0

Dzieje się tak dlatego, że kompilator CPython kieruje go za pomocą [optymalizacji peephole] (http://hg.python.org/cpython/file/ed8b0ee1c531/Python/peephole. C# l405), ale to nie znaczy, że IronPython i Jython robią to samo. –

+0

@MartijnPieters Dobrze, zanotowałem to. Czy wiesz na pewno, czy inne implementacje są lub nie (zakładam, że tak)? – arshajii

+0

Wiem, że optymalizacje peephole nie są częścią specyfikacji języka, więc inne implementacje mogą dodawać je całkowicie lub ignorować. –

8

wierzę not in jest coraz szerzej stosowane.

Podczas gdy przewodnik po stylu PEP 8 nie omawia wyraźnie tematu, uznaje on not in za its own comparison operator.

Nie zapomnij o The Zen of Python. Jedną z głównych zasad pisania Pythona jest to, że "Czytelność się liczy", a więc wybierz ten, który jest najbardziej czytelny w twoim kodzie.

2

Chociaż 4 not in a ma być korzystne, gdy wybór jest w izolacji, nie mogą być przypadki, gdy drugi wybór not 4 in a ma być korzystny.

Na przykład, jeśli specyfikacja oprogramowania zostanie napisana zgodnie z not 4 in a, najlepiej będzie pozostawić specyfikację zgodną ze specyfikacją, aby ułatwić sprawdzanie oprogramowania w odniesieniu do specyfikacji.

Kolejnym przykładem jest fakt, że jednym ze sposobów pozwala ten wyraz pogarszającego się stanu zdrowia:

(4 in well, 
    well, 
    not well, 
    not 4 in well) #!