Yax
Yax

Reputation: 2189

Python in vs ==. Which to Use in this case?

I am making an AJAX call and passing variable pub in it which could be 1 or 0.

As a beginner I want to be double sure of the variable type that is coming in. I am aware I can easily convert to int() and the problem is actually not with AJAX result but it led to this question.

My code:

if pub == 1 or pub == '1':
    #execute funcA()

But the above is not so pythonic for me so I tried:

if pub in [1,'1']:
    #execute funcA()

Which of the above code is better in terms of:

  1. Performance(speed).
  2. Best practice.
  3. Memory usage.

Upvotes: 11

Views: 6307

Answers (6)

Alex
Alex

Reputation: 11

Not really true. If you switch the order you would see different result, just put in order below:

pub = 1
if pub in [1, '1']:
    # execute funcA()
    pass
end1 = datetime.now() - start1
print end1
print end0 - end1

start0 = datetime.now()
if pub == 1 or pub == '1':
    # execute funcA()
    pass
end0 = datetime.now() - start0
print end0
start1 = datetime.now()

Upvotes: 0

rrao
rrao

Reputation: 297

In speed:
in is faster and by a lot.
To prove it, here is the code.

from datetime import datetime

start0 = datetime.now()
pub = 1
if pub == 1 or pub == '1':
    # execute funcA()
    pass
end0 = datetime.now() - start0
print end0
start1 = datetime.now()

if pub in [1, '1']:
    # execute funcA()
    pass
end1 = datetime.now() - start1
print end1
print end0 - end1

Output:

0:00:00.000045
0:00:00.000007
0:00:00.000038

In space: == is a whole lot better.
in takes O(2) space while == takes O(1) space

According to me, the best practice is using in since it is a lot faster and saves a lot of typing

Upvotes: 0

gsb-eng
gsb-eng

Reputation: 1209

1. Performance:

>>> timeit.timeit("pub=1; pub == 1 or pub == '1'", number=10000)
0.0017161369323730469
>>> timeit.timeit("pub=1; pub in[1, '1']", number=10000)
0.0013611316680908203

2. Best Practice: It's good to write programme in a pythonic way I prefer (pub in [1, '1'])

3. Memory Usage: number 1 and string '1' is always cached in python, you can verify the refcount for these objects. So ideally it won't take any extra memory.

>>> sys.getrefcount(1)
833
>>> sys.getrefcount('1')
16

If you use list that needs more memory needs to be allocated to refer these cached objects. (below is in 64 bit type)

>>> sys.getsizeof([1, '1'])
88

These 88 bytes of memory you are gonna allocate extra than the other way of doing.

I would suggest to go with :

if pub in [1,'1']:
    #execute funcA()

Upvotes: 1

The6thSense
The6thSense

Reputation: 8335

So performance wise in is better :

timeit.timeit("pub='1'; pub == 1 or pub == '1'")
0.16224503758795805
timeit.timeit("pub='1'; pub in[1, '1']")
0.13723585976354258
timeit.timeit("pub=1; pub == 1 or pub == '1'")
0.07986264585216674
timeit.timeit("pub=1; pub in[1, '1']")
0.07246544186018866

And as per memory space the if is better since list uses slightly more memory

sys.getsizeof([1,"1"])
44
sys.getsizeof(1)
12
sys.getsizeof("1")
22 
sys.getsizeof("1",1)
22

This is due to the fact that when even empty list is created it takes memory space

sys.getsizeof([])
36

I don't know about the best practice aspect

For me the most pythonic way would be is to use in since it reduces the typing

Upvotes: 3

sinhayash
sinhayash

Reputation: 2803

Performance: in is better

timeit.timeit("pub='1'; pub == 1 or pub == '1'")
0.07568907737731934
timeit.timeit("pub='1'; pub in[1, '1']")
0.04272890090942383
timeit.timeit("pub=1; pub == 1 or pub == '1'")
0.07502007484436035
timeit.timeit("pub=1; pub in[1, '1']")
0.07035684585571289

#other options
timeit.timeit("pub='1'; pub in (1,'1')")
0.04643988609313965
timeit.timeit("pub='1'; pub in {1,'1'}")
0.17076611518859863
timeit.timeit("pub=1; pub in (1,'1')")
0.047419071197509766
timeit.timeit("pub=1; pub in {1,'1'}")
0.1770930290222168

So, {} > or > [] > () based on performance.

Practice: in is preferred as it is less to type. (), [], {} equally good based on practice

Memory:

sys.getsizeof([1,"1"])
88
sys.getsizeof("1",1)
38

#other options
sys.getsizeof(("1",1))
72
sys.getsizeof({"1",1})
232

So, {} > [] > () > or based on memory

Although not asked,, good to know:

Functionality: Value equality and not reference equality

in is just sequential checking equality ==. So similar. in uses == and not is. What I mean to say is this:

>>> a = [1,2,3]
>>> b = [1,a]
>>> b
[1, [1, 2, 3]]
>>> 1 in b
True
>>> a in b
True
>>> [1,2,3] in b
True

So it is implemented not like this:

>>> for i in b:
...     print [1,2,3] is i
... 
False
False

is will return True if two variables point to the same object, == if the objects referred to by the variables are equal. in uses ==

Upvotes: 17

dlask
dlask

Reputation: 8982

This code is better

if pub in [1,'1']:
    #execute funcA()

because it's slightly faster but mainly because it is not redundant. The variable pub appears only once there.

Upvotes: 8

Related Questions