Python "in" operations are automatically returned as true

I wrote this bit of overly complex code on my way to learning how to use the in operator to make if more efficient. I have two questions after the code snippet.

 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" 

First question: I think that if n in listname: automatically returned as True or False. Does anyone know if that is the case?

Second question: the above code returns 3 lines that change depending on whether ans is actually in answer or answer2 . I tried to fix this by replacing the relevant parts as follows:

if ans in answer[i] == True:

This had a strange effect when the code only output the else: . So can anyone explain the difference between how python interprets if ans in answer[i]: and if ans in answer[i] == True: please?

+6
source share
2 answers

To answer your questions in reverse, the reason the explicit comparison with True did not work for you is because Python did not interpret the expression they were expecting. The Python parser has special handling of comparison expressions so that you can combine them and get a reasonable result, for example:

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

Note that Python should treat all this as one operation, because if you split it into two operations, you will not get the same result:

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

They behave differently because the part in brackets is first evaluated and returns True , but True != "a" , so the whole expression returns false.

Right-handed, the above should not actually have any effect on your program. Unfortunately, Python processes in using the same mechanism as == , so when you combine them together, they are interpreted as a sequence similar to the one above, so Python actually evaluates it like this:

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

This is strange and perhaps contrary to intuition, but unfortunately how it works. To get the behavior you need, you need to use parentheses to get Python to evaluate the first part separately:

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

With all that said, == True is redundant, because, as you suspected, the expression already returns a logical expression, and the if can simply evaluate it as it is.

To get back to another problem, I believe that you are trying to make one line of input and create one corresponding line of output, depending on what the user entered. You can apply the in operator to the line and list to see if the line is in the list, which allows you to completely eliminate your for loop:

 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" 

This is the first test if the input matches any of the lines in answer , then the same for answer2 . Of course, you could achieve a similar effect, but also support other forms, such as YeS , by simply converting the input to lower case and comparing it with the lower case form:

 if ans.lower() == "yes": print "Yes!" # (and so forth) 
+15
source

As for the difference between ans in answer[i] and ans in answer[i] == True , it's simple: Python extends this form to ans in answer[i] and answer[i] == True , which of course is False, since the string is not equal to True .

A simpler example may help illustrate this:

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

Note that adding parentheses changes the behavior - this is similar to decompositions like 1 < x < 5 , and not (1 < x) < 5 .

As a side note, it is generally considered a weak style to explicitly check for True or False - it is much better to simply write if x in y .

+5
source

All Articles