0
varA = 1

varB = 2

Code w/ Correct Result:

if type(varA) == type('a') or type(varB) == type('a'):
    print "string involved (either varA or varB is a string)"
else:
    print "varA and varB are not strings"

Code w/ Incorrect Result:

if type(varA) or type(varB) == type('a'):
    print "string involved (either varA or varB is a string)"
else:
    print "varA and varB are not strings"

Why exactly does the 2nd set of code not return the expected result (i.e. "varA and varB are not strings")? What is the step-by-step breakdown of what Python is doing with the 2nd set of code? I found a similar question had already been answered but did not entirely understand the explanation. Python: If-else statements.

3
  • The proper form will be type(varA) is str Commented Jan 18, 2014 at 22:48
  • possible duplicate of if x or y or z == blah Commented Jan 18, 2014 at 23:44
  • @volcano: the better form is isinstance(varA, str), to allow for subclasses. Commented Jan 18, 2014 at 23:45

4 Answers 4

3

In the second code snippet, the condition of the if-statement is being interpreted by Python like this:

if (type(varA)) or (type(varB) == type('a')):

Moreover, it will always evaluate to True.

This is because, no matter what the value of varA is, type(varA) evaluates to True:

>>> varA = 'a'
>>> bool(type(varA))
True
>>> varA = False
>>> bool(type(varA))
True
>>>

In fact, since Python's logical operators short-circuit (stop evaluating as soon as possible), the type(varB) == type('a') part of the condition will never even be evaluated.


On a separate note, you should be using is to compare types:

if type(varA) is str or type(varB) is str:

or, you can use isinstance:

if isinstance(varA, str) or isinstance(varB, str):
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the quick answer! So since {type(varA)} is always {True}, Python will always run the code corresponding to True regardless of the actual type of {varA}.
1

Your second example does not work because it parses as

if (type(varA)) or (type(varB) == type('a')):

and type(varA) will always be a class type which is considered True, so the whole expression will be True


There are better ways to do this

if any(isinstance(v, str) for v in (varA, varB)):

any takes an iterable and evaluates to True if anything in the iterable is true. isinstance checks to see if the first argument "is a" second argument. Placing the generator expression inside of any reads as "if any v in (varA, varB) is a string): ... "

>>> var = 1
>>> isinstance(var, str) # var is an int, not a str
False
>>> isinstance(var, int)
True
>>> isinstance('a', int)
False
>>> isinstance('a', str) # 'a' is a str
True

Comments

0

iCodez is absolutely correct, but if you really want to do something along the lines of "list all elements and check if one of them is a string":

if str in map(type, [varA, varB]):
    print "string involved"

Comments

-1

Because in the second case you are not comparing both variables. Any integer above 0 would return True so you are not comparing types here.

if type(varA):

will always be True, because varA is equal to 1. You never even get to the second part of the condition.

4 Comments

Wrong, type(0) is int.
Not what I said. type(0) is int, but it's also False according to python. Check: if 0 == False: print 123
type(varA) is not an integer. And any non-0 value - integer or float - evaluates to True in boolean expression. Here is my piece of code for you if -1: print "Alex Hristov is wrong" ;-)
Look at the original post. varA = 1 . varA is clearly an integer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.