2013-03-22 6 views
6

Napisałem trochę niepotrzebnie skomplikowanego kodu, aby dowiedzieć się, jak używać instrukcji in, aby lepiej wykonywać instrukcje if. Mam dwa pytania po fragmencie kodu.Pythonowe instrukcje "in" automatycznie zwracają się jako prawdziwe

answer = ['Yes', 'yes', 'YES'] 
answer2 = ['No', 'no', 'NO'] 
ans = raw_input() 
for i in range(0, 3): 
    if ans in answer[i]: 
     print "Yes!" 
    elif ans in answer2[i]: 
     print "No!" 
    else: 
     print "Don't know what that means" 

Pierwsze pytanie: Myślę automatycznie if n in listname: powraca jako Prawda lub Fałsz. Czy ktoś wie, czy tak jest?

Drugie pytanie: powyższy kod zwraca 3 linie, które różnią się w zależności od tego, czy ans jest rzeczywiście w answer lub answer2. Starałem się wyeliminować że zastępując odpowiednie porcje tak:

if ans in answer[i] == True:

Miało dziwny efekt dokonywania Kod wyjścia tylko oświadczenie else:. Czy ktoś może mi wyjaśnić różnicę między tym, jak python interpretuje if ans in answer[i]: i if ans in answer[i] == True:, proszę?

Odpowiedz

5

Jeśli chodzi o różnicę między ans in answer[i] i ans in answer[i] == True, prosta: Python rozszerza tę drugą formę się ans in answer[i] and answer[i] == True, co jest, oczywiście, False ponieważ łańcuch nie jest równa True.

Prostszy przykład może pomóc zilustrować następująco:

>>> a = [1, 2, 3] 
>>> 2 in a 
True 
>>> 2 in a == True 
False 
>>> 2 in a and a == True 
False 
>>> (2 in a) == True 
True 
>>> 2 in a == [1, 2, 3] 
True 
>>> 2 in a and a == [1, 2, 3] 
True 

Wskazówki jak dodanie nawiasów zmienia zachowanie - jest zbliżona do rozszerzalności jak 1 < x < 5, w przeciwieństwie do (1 < x) < 5.

Na marginesie uznano, że złym stylem jest jednoznaczne sprawdzenie pod kątem True lub False - o wiele lepiej jest po prostu napisać if x in y.

15

Aby odpowiedzieć na Twoje pytania w odwrotnej kolejności, powodem, dla którego jawne porównanie z True nie zadziałało, jest to, że Python nie interpretował wyrażenia zgodnie z oczekiwaniami. Python parser ma specjalną obsługę porównać wyrażeń, dzięki czemu można łańcucha je razem i dostać sensowny rezultat, tak:

>>> "a" == "a" == "a" 
True 

Zauważ, że Python ma traktować tę całą rzecz jako jednej operacji, ponieważ jeśli go podzielić w dwóch operacjach albo sposób nie uzyskać ten sam rezultat:

>>> ("a" == "a") == "a" 
False 
>>> "a" == ("a" == "a") 
False 

te zachowują się inaczej, ponieważ część w nawiasach jest oceniany pierwszy i zwraca True, ale True != "a" więc całe wyrażenie zwraca wartość false.

Według prawa powyższe informacje w rzeczywistości nie powinny mieć żadnego wpływu na program. Niestety, Python obsługuje in za pośrednictwem tego samego mechanizmu co == więc kiedy łańcuch te razem są one interpretowane jako sekwencję jak wyżej, więc Python rzeczywiście ocenia je następująco:

>> "a" in ["a"] == True 
False 
>>> ("a" in ["a"]) and ("a" == True) 
False 

To zwariowana i prawdopodobnie sprzeczne z intuicją, ale to niestety tylko jak to działa.Aby uzyskać zachowanie chciałeś trzeba użyć nawiasów, aby zmusić Pythona do oceny pierwszej części oddzielnie:

>>> ("a" in ["a"]) == True 
True 

Z wszystkich, że powiedziałem, == True jest zbędny, ponieważ, jak podejrzewał, ekspresja już zwraca wartość logiczną i oświadczenie if może po prostu ocenić je tak, jak jest.

Aby teraz powrócić do innego problemu, uważam, że próbujesz wykonać jedną linię danych wejściowych i wytworzyć jedną odpowiadającą linię wyjściową w zależności od wprowadzonego przez użytkownika. Można zastosować operator in na ciąg i listy, aby sprawdzić, czy ciąg jest na liście, która pozwala wyeliminować pętlę for sumie:

answer = ['Yes', 'yes', 'YES'] 
answer2 = ['No', 'no', 'NO'] 
ans = raw_input() 
if ans in answer: 
    print "Yes!" 
elif ans in answer2: 
    print "No!" 
else: 
    print "Don't know what that means" 

tej pierwszej próby, jeśli wejście mecze każdy z ciągów w answer, to samo dla answer2. Oczywiście można osiągnąć podobny efekt, ale można także obsługiwać inne formy, na przykład YeS, konwertując dane wejściowe na małe litery i porównując je z małą literą:

if ans.lower() == "yes": 
    print "Yes!" 
# (and so forth) 
Powiązane problemy