Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compound boolean logic in python if

Tags:

python

I am trying to test a basic premise in python and it always fails and I can't figure out why.

My sys.argv looks like this:

['test.py', 'test']

And my code looks like this:

if len(sys.argv) > 1 and sys.argv[1] is 'test':
    print 'Test mode'

But the test is never true. I am sure that I am missing something really simple here, but I can't figure out what it is.

like image 594
thaBadDawg Avatar asked Nov 22 '12 01:11

thaBadDawg


People also ask

How do you check if a Boolean value is in if in Python?

Remember that True and False are Booleans in Python. This means that if and other conditional statements will use Boolean math to compute their Boolean state. You should also note the need for a colon ( : ) at the end of the if statement. This is needed at the end of a control flow statement.

What is compound Boolean expression in Python?

Using Python's and Operator With Boolean Expressions You'll typically use logical operators to build compound Boolean expressions, which are combinations of variables and values that produce a Boolean value as a result. In other words, Boolean expressions return True or False .

What is the difference between IS and == in Python?

The == operator compares the value or equality of two objects, whereas the Python is operator checks whether two variables point to the same object in memory. In the vast majority of cases, this means you should use the equality operators == and !=

How are Boolean expressions used in if statements?

The simplest if-statement has two parts – a boolean "test" within parentheses ( ) followed by "body" block of statements within curly braces { }. The test can be any expression that evaluates to a boolean value – true or false – value (boolean expressions are detailed below).


1 Answers

As mentioned above, the main reason is your test comparison. Using is is different than using == as it compares if two objects are equal. In this case, you can verify that they are not equal by checking their ids:

import sys

print id(sys.argv[1])
print id('test')

My output:

140335994263232
140335994263424

As they point to different objects, they will not be equal when using is (but using == will compare the strings themselves, which will return True).

The issue at work here is the concept of interning. When you hardcode two identical strings into your source, the strings are interned and the two will share an object ID (this explains @SamMussmann's very valid point below). But when you pass a string in via argv, a new object is created, thereby making the comparison to an identical hardcoded string in your code return False. The best explanation I have found so far is in here, where both Alex Martelli and Jon Skeet (two very reputable sources) explain interning and when strings are interned. From these explanations, it does seem that since the data from argv is external to the program, the values aren't interned, and therefore have different object IDs than if they were both literals in the source.

One additional point of interest (unrelated to the issue at hand but pertinent to the is discussion) is the caching that is done with numbers. The numbers from -5 to 256 are cached, meaning that is comparisons with equal numbers in that range will be True, regardless of how they are calculated:

In [1]: 256 is 255 + 1
Out[1]: True

In [2]: 257 is 256 + 1
Out[2]: False

In [3]: -5 is -4 - 1
Out[3]: True

In [4]: -6 is -5 - 1
Out[4]: False
like image 126
RocketDonkey Avatar answered Sep 30 '22 10:09

RocketDonkey