user10501
user10501

Reputation: 41

Why different results from an if-statement in Python 3 and C?

I hoped that the values printed would be "200!" and "404!" in Python3.4. But I got the results "200!" and "else!".

I made a strange face — and tried it again in C. The results in C are not the same as those in Python3. Why?

Python3.4 code

def chk(s): 
    if s is 200:
        print('200!')
    elif s is 404:
        print('404!')
    else:
        print('else!')

chk(200)
chk(404)

Python3.4 code result

200!
else!

C code

#include <stdio.h>

void chk(int s) {
    if (s == 200)
        printf("200!");
    else if (s == 404)
        printf("404!");
    else
        printf("else!");
}

int main(void) {
    chk(200);
    chk(404);
    return 0;
}

C code result

200!404!

Upvotes: 3

Views: 113

Answers (2)

too honest for this site
too honest for this site

Reputation: 12263

is basically compares for identity of an object. Note that Python names are just references to the actual objects. So, the C equivalent would be basically:

int k = 200, *i;
const int c = 200;

i = &k;

if ( i == &c )
    // fails, but *i == c is true
    .... 

So, you should not use is to compare values for equality, but for identity only. The most important use-case is:

if val is None:
    ...

As there is exactly one None object.

if val == None:
    ...

OTOH will be subject to coercion rules, thus be True for various other cases, too.

Read here (search the paragraph about is) and the footnote for details.

Upvotes: 1

NightShadeQueen
NightShadeQueen

Reputation: 3335

is doesn't mean "equal", per se. It actually means "occupies the same location in memory." Additionally, using is on numbers has odd behavior, depending on which version of python you're using. (And by this, I mean Cpython vs Jpython vs pypy vs....) So don't use it, use == for numbers.

def chk(s): 
    if s == 200:
        print('200!')
    elif s == 404:
        print('404!')
    else:
        print('else!')

chk(200)
chk(404)

(If you want more details to why 200 is 200 yields True but 404 is 404 yields False: basically, numbers from -5 to 256 are cached in CPython. They each get their little slot of memory, and if they're assigned to a variable, CPython just sort of points that variable towards the preassigned slot of memory. This is not the case for numbers outside that range. If those are needed, CPython will go find an empty slot of memory, put the number there, and point the variable at it. If you assign 404 to two separate variables, you have two separate integers of 404 hanging out in memory.)

For more:

When to use is, when to use ==.

CPython, is, and why you should never use it with numbers

Upvotes: 7

Related Questions